Merge "Wipe only managed profile when max number of incorrect passwords exceeded" into lmp-dev
diff --git a/Android.mk b/Android.mk
index 8309301..5485e9f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -128,6 +128,7 @@
 	core/java/android/content/pm/IOnAppsChangedListener.aidl \
 	core/java/android/content/pm/IPackageDataObserver.aidl \
 	core/java/android/content/pm/IPackageDeleteObserver.aidl \
+	core/java/android/content/pm/IPackageDeleteObserver2.aidl \
 	core/java/android/content/pm/IPackageInstallObserver.aidl \
 	core/java/android/content/pm/IPackageInstallObserver2.aidl \
 	core/java/android/content/pm/IPackageInstaller.aidl \
@@ -361,6 +362,8 @@
 	telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl \
 	telephony/java/com/android/ims/internal/IImsConfig.aidl \
 	telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl \
+	telephony/java/com/android/ims/internal/IImsEcbm.aidl \
+	telephony/java/com/android/ims/internal/IImsEcbmListener.aidl \
 	telephony/java/com/android/ims/internal/IImsService.aidl \
 	telephony/java/com/android/ims/internal/IImsStreamMediaSession.aidl \
 	telephony/java/com/android/ims/internal/IImsUt.aidl \
@@ -628,7 +631,7 @@
     -since $(SRC_API_DIR)/18.txt 18 \
     -since $(SRC_API_DIR)/19.txt 19 \
     -since $(SRC_API_DIR)/20.txt 20 \
-		-werror -hide 113 \
+		-werror -hide 111 -hide 113 \
 		-overview $(LOCAL_PATH)/core/java/overview.html
 
 framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR:= \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index fff8a85..ae2f3ad 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -214,6 +214,10 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework.* $(PRODUCT_OUT)/system/framework2.*)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/docs/api-stubs-timestamp)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/services.core_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/services_intermediates)
 
 # ******************************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
diff --git a/api/current.txt b/api/current.txt
index a8bbeed..d4f2cc5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4697,6 +4697,7 @@
     field public android.os.Bundle extras;
     field public int flags;
     field public android.app.PendingIntent fullScreenIntent;
+    field public android.widget.RemoteViews headsUpContentView;
     field public int icon;
     field public int iconLevel;
     field public android.graphics.Bitmap largeIcon;
@@ -5379,6 +5380,7 @@
 
   public class DevicePolicyManager {
     method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int);
+    method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
     method public void addPersistentPreferredActivity(android.content.ComponentName, android.content.IntentFilter, android.content.ComponentName);
     method public void addUserRestriction(android.content.ComponentName, java.lang.String);
     method public void clearCrossProfileIntentFilters(android.content.ComponentName);
@@ -5395,6 +5397,7 @@
     method public boolean getBlockUninstall(android.content.ComponentName, java.lang.String);
     method public boolean getCameraDisabled(android.content.ComponentName);
     method public boolean getCrossProfileCallerIdDisabled(android.content.ComponentName);
+    method public java.util.List<java.lang.String> getCrossProfileWidgetProviders(android.content.ComponentName);
     method public int getCurrentFailedPasswordAttempts();
     method public int getKeyguardDisabledFeatures(android.content.ComponentName);
     method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
@@ -5428,6 +5431,7 @@
     method public boolean isProfileOwnerApp(java.lang.String);
     method public void lockNow();
     method public void removeActiveAdmin(android.content.ComponentName);
+    method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
     method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
     method public boolean resetPassword(java.lang.String, int);
     method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
@@ -5733,6 +5737,7 @@
     method protected android.appwidget.AppWidgetHostView onCreateView(android.content.Context, int, android.appwidget.AppWidgetProviderInfo);
     method protected void onProviderChanged(int, android.appwidget.AppWidgetProviderInfo);
     method protected void onProvidersChanged();
+    method public final void startAppWidgetConfigureActivityForResult(android.app.Activity, android.content.Intent, int);
     method public void startListening();
     method public void stopListening();
   }
@@ -5755,10 +5760,12 @@
   public class AppWidgetManager {
     method public boolean bindAppWidgetIdIfAllowed(int, android.content.ComponentName);
     method public boolean bindAppWidgetIdIfAllowed(int, android.content.ComponentName, android.os.Bundle);
+    method public boolean bindAppWidgetIdIfAllowed(int, android.os.UserHandle, android.content.ComponentName, android.os.Bundle);
     method public int[] getAppWidgetIds(android.content.ComponentName);
     method public android.appwidget.AppWidgetProviderInfo getAppWidgetInfo(int);
     method public android.os.Bundle getAppWidgetOptions(int);
     method public java.util.List<android.appwidget.AppWidgetProviderInfo> getInstalledProviders();
+    method public java.util.List<android.appwidget.AppWidgetProviderInfo> getInstalledProvidersForProfiles(android.os.UserHandle[]);
     method public static android.appwidget.AppWidgetManager getInstance(android.content.Context);
     method public void notifyAppWidgetViewDataChanged(int[], int);
     method public void notifyAppWidgetViewDataChanged(int, int);
@@ -5783,6 +5790,7 @@
     field public static final java.lang.String EXTRA_APPWIDGET_OLD_IDS = "appWidgetOldIds";
     field public static final java.lang.String EXTRA_APPWIDGET_OPTIONS = "appWidgetOptions";
     field public static final java.lang.String EXTRA_APPWIDGET_PROVIDER = "appWidgetProvider";
+    field public static final java.lang.String EXTRA_APPWIDGET_PROVIDER_PROFILE = "appWidgetProviderProfile";
     field public static final java.lang.String EXTRA_CUSTOM_EXTRAS = "customExtras";
     field public static final java.lang.String EXTRA_CUSTOM_INFO = "customInfo";
     field public static final java.lang.String EXTRA_HOST_ID = "hostId";
@@ -5811,6 +5819,10 @@
     ctor public AppWidgetProviderInfo(android.os.Parcel);
     method public android.appwidget.AppWidgetProviderInfo clone();
     method public int describeContents();
+    method public final android.os.UserHandle getProfile();
+    method public final android.graphics.drawable.Drawable loadIcon(android.content.Context, int);
+    method public final java.lang.String loadLabel(android.content.pm.PackageManager);
+    method public final android.graphics.drawable.Drawable loadPreviewImage(android.content.Context, int);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int RESIZE_BOTH = 3; // 0x3
@@ -5825,7 +5837,7 @@
     field public int icon;
     field public int initialKeyguardLayout;
     field public int initialLayout;
-    field public java.lang.String label;
+    field public deprecated java.lang.String label;
     field public int minHeight;
     field public int minResizeHeight;
     field public int minResizeWidth;
@@ -6581,22 +6593,20 @@
     method public int describeContents();
     method public boolean getIncludeDeviceName();
     method public boolean getIncludeTxPowerLevel();
-    method public int getManufacturerId();
-    method public byte[] getManufacturerSpecificData();
-    method public byte[] getServiceData();
-    method public android.os.ParcelUuid getServiceDataUuid();
+    method public android.util.SparseArray<byte[]> getManufacturerSpecificData();
+    method public java.util.Map<android.os.ParcelUuid, byte[]> getServiceData();
     method public java.util.List<android.os.ParcelUuid> getServiceUuids();
     method public void writeToParcel(android.os.Parcel, int);
   }
 
   public static final class AdvertiseData.Builder {
     ctor public AdvertiseData.Builder();
+    method public android.bluetooth.le.AdvertiseData.Builder addManufacturerData(int, byte[]);
+    method public android.bluetooth.le.AdvertiseData.Builder addServiceData(android.os.ParcelUuid, byte[]);
     method public android.bluetooth.le.AdvertiseData.Builder addServiceUuid(android.os.ParcelUuid);
     method public android.bluetooth.le.AdvertiseData build();
     method public android.bluetooth.le.AdvertiseData.Builder setIncludeDeviceName(boolean);
     method public android.bluetooth.le.AdvertiseData.Builder setIncludeTxPowerLevel(boolean);
-    method public android.bluetooth.le.AdvertiseData.Builder setManufacturerData(int, byte[]);
-    method public android.bluetooth.le.AdvertiseData.Builder setServiceData(android.os.ParcelUuid, byte[]);
   }
 
   public final class AdvertiseSettings implements android.os.Parcelable {
@@ -6657,6 +6667,7 @@
     method public int getManufacturerId();
     method public byte[] getServiceData();
     method public byte[] getServiceDataMask();
+    method public android.os.ParcelUuid getServiceDataUuid();
     method public android.os.ParcelUuid getServiceUuid();
     method public android.os.ParcelUuid getServiceUuidMask();
     method public boolean matches(android.bluetooth.le.ScanResult);
@@ -6680,10 +6691,10 @@
     method public int getAdvertiseFlags();
     method public byte[] getBytes();
     method public java.lang.String getDeviceName();
-    method public int getManufacturerId();
-    method public byte[] getManufacturerSpecificData();
-    method public byte[] getServiceData();
-    method public android.os.ParcelUuid getServiceDataUuid();
+    method public android.util.SparseArray<byte[]> getManufacturerSpecificData();
+    method public byte[] getManufacturerSpecificData(int);
+    method public java.util.Map<android.os.ParcelUuid, byte[]> getServiceData();
+    method public byte[] getServiceData(android.os.ParcelUuid);
     method public java.util.List<android.os.ParcelUuid> getServiceUuids();
     method public int getTxPowerLevel();
   }
@@ -7277,6 +7288,7 @@
     field public static final java.lang.String ACCOUNT_SERVICE = "account";
     field public static final java.lang.String ACTIVITY_SERVICE = "activity";
     field public static final java.lang.String ALARM_SERVICE = "alarm";
+    field public static final java.lang.String APPWIDGET_SERVICE = "appwidget";
     field public static final java.lang.String APP_OPS_SERVICE = "appops";
     field public static final java.lang.String AUDIO_SERVICE = "audio";
     field public static final java.lang.String BATTERY_SERVICE = "batterymanager";
@@ -8661,6 +8673,7 @@
     ctor public PackageInstaller.CommitCallback();
     method public abstract void onFailure(int, java.lang.String, android.os.Bundle);
     method public abstract void onSuccess();
+    method public abstract void onUserActionRequired(android.content.Intent);
     field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.content.pm.extra.PACKAGE_NAME";
     field public static final int FAILURE_CONFLICT = 2; // 0x2
     field public static final int FAILURE_INCOMPATIBLE = 4; // 0x4
@@ -8693,6 +8706,7 @@
     ctor public PackageInstaller.UninstallCallback();
     method public abstract void onFailure(java.lang.String);
     method public abstract void onSuccess();
+    method public abstract void onUserActionRequired(android.content.Intent);
   }
 
   public class PackageItemInfo {
@@ -10983,8 +10997,10 @@
     ctor public Outline();
     ctor public Outline(android.graphics.Outline);
     method public boolean canClip();
+    method public float getAlpha();
     method public boolean isEmpty();
     method public void set(android.graphics.Outline);
+    method public void setAlpha(float);
     method public void setConvexPath(android.graphics.Path);
     method public void setEmpty();
     method public void setOval(int, int, int, int);
@@ -11763,7 +11779,9 @@
     method public void setHotspotBounds(int, int, int, int);
     method public final boolean setLevel(int);
     method public boolean setState(int[]);
-    method public void setTint(android.content.res.ColorStateList, android.graphics.PorterDuff.Mode);
+    method public void setTint(int);
+    method public void setTintList(android.content.res.ColorStateList);
+    method public void setTintMode(android.graphics.PorterDuff.Mode);
     method public boolean setVisible(boolean, boolean);
     method public void unscheduleSelf(java.lang.Runnable);
   }
@@ -13233,6 +13251,7 @@
     method public android.view.Display getDisplay();
     method public android.view.Surface getSurface();
     method public void release();
+    method public void resize(int, int, int);
     method public void setSurface(android.view.Surface);
   }
 
@@ -14107,6 +14126,9 @@
   }
 
   public class AudioFormat {
+    method public int getChannelMask();
+    method public int getEncoding();
+    method public int getSampleRate();
     field public static final deprecated int CHANNEL_CONFIGURATION_DEFAULT = 1; // 0x1
     field public static final deprecated int CHANNEL_CONFIGURATION_INVALID = 0; // 0x0
     field public static final deprecated int CHANNEL_CONFIGURATION_MONO = 2; // 0x2
@@ -15113,6 +15135,7 @@
     method public long getLong(java.lang.String);
     method public android.media.Rating getRating(java.lang.String);
     method public java.lang.String getString(java.lang.String);
+    method public java.lang.CharSequence getText(java.lang.String);
     method public java.util.Set<java.lang.String> keySet();
     method public int size();
     method public void writeToParcel(android.os.Parcel, int);
@@ -15129,6 +15152,11 @@
     field public static final java.lang.String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER";
     field public static final java.lang.String METADATA_KEY_DATE = "android.media.metadata.DATE";
     field public static final java.lang.String METADATA_KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_DESCRIPTION = "android.media.metadata.DISPLAY_DESCRIPTION";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_ICON = "android.media.metadata.DISPLAY_ICON";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_ICON_URI = "android.media.metadata.DISPLAY_ICON_URI";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_SUBTITLE = "android.media.metadata.DISPLAY_SUBTITLE";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_TITLE = "android.media.metadata.DISPLAY_TITLE";
     field public static final java.lang.String METADATA_KEY_DURATION = "android.media.metadata.DURATION";
     field public static final java.lang.String METADATA_KEY_GENRE = "android.media.metadata.GENRE";
     field public static final java.lang.String METADATA_KEY_NUM_TRACKS = "android.media.metadata.NUM_TRACKS";
@@ -15148,6 +15176,7 @@
     method public android.media.MediaMetadata.Builder putLong(java.lang.String, long);
     method public android.media.MediaMetadata.Builder putRating(java.lang.String, android.media.Rating);
     method public android.media.MediaMetadata.Builder putString(java.lang.String, java.lang.String);
+    method public android.media.MediaMetadata.Builder putText(java.lang.String, java.lang.CharSequence);
   }
 
   public abstract deprecated class MediaMetadataEditor {
@@ -16231,6 +16260,7 @@
     method public void disconnect();
     method public android.os.Bundle getExtras();
     method public android.net.Uri getRoot();
+    method public android.content.ComponentName getServiceComponent();
     method public android.media.session.MediaSession.Token getSessionToken();
     method public boolean isConnected();
     method public void loadIcon(android.net.Uri, int, int, android.media.browse.MediaBrowser.IconCallback);
@@ -16631,12 +16661,14 @@
     method public void adjustVolume(int, int);
     method public android.media.routing.MediaRouter.Delegate createMediaRouterDelegate();
     method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
+    method public android.os.Bundle getExtras();
     method public long getFlags();
     method public android.app.PendingIntent getLaunchActivity();
     method public android.media.MediaMetadata getMetadata();
     method public java.lang.String getPackageName();
     method public android.media.session.PlaybackState getPlaybackState();
     method public java.util.List<android.media.session.MediaSession.Track> getQueue();
+    method public java.lang.CharSequence getQueueTitle();
     method public int getRatingType();
     method public android.media.session.MediaSession.Token getSessionToken();
     method public android.media.session.MediaController.TransportControls getTransportControls();
@@ -16844,9 +16876,8 @@
 package android.media.tv {
 
   public final class TvContentRating {
-    method public static android.media.tv.TvContentRating createRating(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String...);
+    method public static android.media.tv.TvContentRating createRating(java.lang.String, java.lang.String, java.lang.String, java.lang.String...);
     method public java.lang.String flattenToString();
-    method public java.lang.String getCountry();
     method public java.lang.String getDomain();
     method public java.lang.String getMainRating();
     method public java.lang.String getRatingSystem();
@@ -17033,22 +17064,6 @@
     method public void onInputStateChanged(java.lang.String, int);
   }
 
-  public abstract class TvInputPassthroughWrapperService extends android.media.tv.TvInputService {
-    ctor public TvInputPassthroughWrapperService();
-    method public abstract java.lang.String getPassthroughInputId(java.lang.String);
-    method public abstract android.media.tv.TvInputPassthroughWrapperService.PassthroughWrapperSession onCreatePassthroughWrapperSession();
-    method public final android.media.tv.TvInputService.Session onCreateSession(java.lang.String);
-  }
-
-  public abstract class TvInputPassthroughWrapperService.PassthroughWrapperSession extends android.media.tv.TvInputService.Session {
-    ctor public TvInputPassthroughWrapperService.PassthroughWrapperSession();
-    method public abstract void onPassthroughSessionCreationFailed();
-    method public abstract void onPassthroughSessionReleased();
-    method public abstract void onPassthroughVideoAvailable();
-    method public abstract void onPassthroughVideoUnavailable(int);
-    method public final boolean onSetSurface(android.view.Surface);
-  }
-
   public abstract class TvInputService extends android.app.Service {
     ctor public TvInputService();
     method public final android.os.IBinder onBind(android.content.Intent);
@@ -17057,13 +17072,21 @@
     field public static final java.lang.String SERVICE_META_DATA = "android.media.tv.input";
   }
 
-  public abstract class TvInputService.Session implements android.view.KeyEvent.Callback {
-    ctor public TvInputService.Session();
+  public static abstract class TvInputService.HardwareSession extends android.media.tv.TvInputService.Session {
+    ctor public TvInputService.HardwareSession(android.content.Context);
+    method public abstract java.lang.String getHardwareInputId();
+    method public void onHardwareVideoAvailable();
+    method public void onHardwareVideoUnavailable(int);
+    method public final boolean onSetSurface(android.view.Surface);
+  }
+
+  public static abstract class TvInputService.Session implements android.view.KeyEvent.Callback {
+    ctor public TvInputService.Session(android.content.Context);
     method public void notifyChannelRetuned(android.net.Uri);
     method public void notifyContentAllowed();
     method public void notifyContentBlocked(android.media.tv.TvContentRating);
-    method public void notifyTrackInfoChanged(java.util.List<android.media.tv.TvTrackInfo>);
-    method public void notifyTrackSelectionChanged(java.util.List<android.media.tv.TvTrackInfo>);
+    method public void notifyTrackSelected(int, java.lang.String);
+    method public void notifyTracksChanged(java.util.List<android.media.tv.TvTrackInfo>);
     method public void notifyVideoAvailable();
     method public void notifyVideoUnavailable(int);
     method public android.view.View onCreateOverlayView();
@@ -17073,7 +17096,7 @@
     method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
     method public boolean onKeyUp(int, android.view.KeyEvent);
     method public abstract void onRelease();
-    method public boolean onSelectTrack(android.media.tv.TvTrackInfo);
+    method public boolean onSelectTrack(int, java.lang.String);
     method public abstract void onSetCaptionEnabled(boolean);
     method public abstract void onSetStreamVolume(float);
     method public abstract boolean onSetSurface(android.view.Surface);
@@ -17082,7 +17105,6 @@
     method public boolean onTrackballEvent(android.view.MotionEvent);
     method public abstract boolean onTune(android.net.Uri);
     method public void onUnblockContent(android.media.tv.TvContentRating);
-    method public boolean onUnselectTrack(android.media.tv.TvTrackInfo);
     method public void setOverlayViewEnabled(boolean);
   }
 
@@ -17091,6 +17113,7 @@
     method public final int getAudioChannelCount();
     method public final int getAudioSampleRate();
     method public final android.os.Bundle getExtra();
+    method public final java.lang.String getId();
     method public final java.lang.String getLanguage();
     method public final int getType();
     method public final int getVideoHeight();
@@ -17103,7 +17126,7 @@
   }
 
   public static final class TvTrackInfo.Builder {
-    ctor public TvTrackInfo.Builder(int);
+    ctor public TvTrackInfo.Builder(int, java.lang.String);
     method public android.media.tv.TvTrackInfo build();
     method public final android.media.tv.TvTrackInfo.Builder setAudioChannelCount(int);
     method public final android.media.tv.TvTrackInfo.Builder setAudioSampleRate(int);
@@ -17118,18 +17141,17 @@
     ctor public TvView(android.content.Context, android.util.AttributeSet);
     ctor public TvView(android.content.Context, android.util.AttributeSet, int);
     method public boolean dispatchUnhandledInputEvent(android.view.InputEvent);
-    method public java.util.List<android.media.tv.TvTrackInfo> getSelectedTracks();
-    method public java.util.List<android.media.tv.TvTrackInfo> getTracks();
+    method public java.lang.String getSelectedTrack(int);
+    method public java.util.List<android.media.tv.TvTrackInfo> getTracks(int);
     method protected void onLayout(boolean, int, int, int, int);
     method public boolean onUnhandledInputEvent(android.view.InputEvent);
     method public void reset();
-    method public void selectTrack(android.media.tv.TvTrackInfo);
+    method public void selectTrack(int, java.lang.String);
     method public void setCaptionEnabled(boolean);
     method public void setOnUnhandledInputEventListener(android.media.tv.TvView.OnUnhandledInputEventListener);
     method public void setStreamVolume(float);
     method public void setTvInputListener(android.media.tv.TvView.TvInputListener);
     method public void tune(java.lang.String, android.net.Uri);
-    method public void unselectTrack(android.media.tv.TvTrackInfo);
     field public static final int ERROR_INPUT_DISCONNECTED = 1; // 0x1
     field public static final int ERROR_INPUT_NOT_CONNECTED = 0; // 0x0
   }
@@ -17144,8 +17166,8 @@
     method public void onContentAllowed(java.lang.String);
     method public void onContentBlocked(java.lang.String, android.media.tv.TvContentRating);
     method public void onError(java.lang.String, int);
-    method public void onTrackInfoChanged(java.lang.String, java.util.List<android.media.tv.TvTrackInfo>);
-    method public void onTrackSelectionChanged(java.lang.String, java.util.List<android.media.tv.TvTrackInfo>);
+    method public void onTrackSelected(java.lang.String, int, java.lang.String);
+    method public void onTracksChanged(java.lang.String, java.util.List<android.media.tv.TvTrackInfo>);
     method public void onVideoAvailable(java.lang.String);
     method public void onVideoSizeChanged(java.lang.String, int, int);
     method public void onVideoUnavailable(java.lang.String, int);
@@ -22755,7 +22777,8 @@
 
   public class UserManager {
     method public android.os.Bundle getApplicationRestrictions(java.lang.String);
-    method public android.graphics.drawable.Drawable getBadgedDrawableForUser(android.graphics.drawable.Drawable, android.os.UserHandle);
+    method public android.graphics.drawable.Drawable getBadgedDrawableForUser(android.graphics.drawable.Drawable, android.os.UserHandle, android.graphics.Rect, int);
+    method public android.graphics.drawable.Drawable getBadgedIconForUser(android.graphics.drawable.Drawable, android.os.UserHandle);
     method public java.lang.CharSequence getBadgedLabelForUser(java.lang.CharSequence, android.os.UserHandle);
     method public long getSerialNumberForUser(android.os.UserHandle);
     method public int getUserCount();
@@ -27490,11 +27513,12 @@
   public class AlwaysOnHotwordDetector {
     method public android.content.Intent getManageIntent(int);
     method public int getSupportedRecognitionModes();
-    method public void startRecognition(int);
-    method public void stopRecognition();
+    method public boolean startRecognition(int);
+    method public boolean stopRecognition();
     field public static final int MANAGE_ACTION_ENROLL = 0; // 0x0
     field public static final int MANAGE_ACTION_RE_ENROLL = 1; // 0x1
     field public static final int MANAGE_ACTION_UN_ENROLL = 2; // 0x2
+    field public static final int RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS = 2; // 0x2
     field public static final int RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO = 1; // 0x1
     field public static final int RECOGNITION_FLAG_NONE = 0; // 0x0
     field public static final int RECOGNITION_MODE_USER_IDENTIFICATION = 2; // 0x2
@@ -27507,12 +27531,15 @@
 
   public static abstract interface AlwaysOnHotwordDetector.Callback {
     method public abstract void onAvailabilityChanged(int);
-    method public abstract void onDetected(byte[]);
-    method public abstract void onDetectionStarted();
-    method public abstract void onDetectionStopped();
+    method public abstract void onDetected(android.service.voice.AlwaysOnHotwordDetector.TriggerAudio);
     method public abstract void onError();
   }
 
+  public static class AlwaysOnHotwordDetector.TriggerAudio {
+    field public final android.media.AudioFormat audioFormat;
+    field public final byte[] data;
+  }
+
   public class VoiceInteractionService extends android.app.Service {
     ctor public VoiceInteractionService();
     method public final android.service.voice.AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(java.lang.String, java.lang.String, android.service.voice.AlwaysOnHotwordDetector.Callback);
@@ -28546,10 +28573,11 @@
   public final class Call {
     method public void addListener(android.telecomm.Call.Listener);
     method public void answer(int);
-    method public void conference();
+    method public void conference(android.telecomm.Call);
     method public void disconnect();
     method public java.util.List<java.lang.String> getCannedTextResponses();
     method public java.util.List<android.telecomm.Call> getChildren();
+    method public java.util.List<android.telecomm.Call> getConferenceableCalls();
     method public android.telecomm.Call.Details getDetails();
     method public android.telecomm.Call getParent();
     method public java.lang.String getRemainingPostDialSequence();
@@ -28577,9 +28605,9 @@
 
   public static class Call.Details {
     method public android.telecomm.PhoneAccountHandle getAccountHandle();
+    method public int getCallCapabilities();
     method public java.lang.String getCallerDisplayName();
     method public int getCallerDisplayNamePresentation();
-    method public int getCapabilities();
     method public long getConnectTimeMillis();
     method public int getDisconnectCauseCode();
     method public java.lang.String getDisconnectCauseMsg();
@@ -28595,9 +28623,9 @@
     method public void onCallDestroyed(android.telecomm.Call);
     method public void onCannedTextResponsesLoaded(android.telecomm.Call, java.util.List<java.lang.String>);
     method public void onChildrenChanged(android.telecomm.Call, java.util.List<android.telecomm.Call>);
+    method public void onConferenceableCallsChanged(android.telecomm.Call, java.util.List<android.telecomm.Call>);
     method public void onDetailsChanged(android.telecomm.Call, android.telecomm.Call.Details);
     method public void onParentChanged(android.telecomm.Call, android.telecomm.Call);
-    method public void onPostDial(android.telecomm.Call, java.lang.String);
     method public void onPostDialWait(android.telecomm.Call, java.lang.String);
     method public void onStartActivity(android.telecomm.Call, android.app.PendingIntent);
     method public void onStateChanged(android.telecomm.Call, int);
@@ -28692,6 +28720,7 @@
     method public void onAbort();
     method public void onAnswer(int);
     method public void onChildrenChanged(java.util.List<android.telecomm.Connection>);
+    method public void onConferenceWith(android.telecomm.Connection);
     method public void onDisconnect();
     method public void onHold();
     method public void onPhoneAccountClicked();
@@ -28709,6 +28738,7 @@
     method public final void setCallCapabilities(int);
     method public final void setCallerDisplayName(java.lang.String, int);
     method public final void setCanceled();
+    method public final void setConferenceableConnections(java.util.List<android.telecomm.Connection>);
     method public final void setDialing();
     method public final void setDisconnected(int, java.lang.String);
     method public final void setFailed(int, java.lang.String);
@@ -28779,16 +28809,16 @@
     method public void changeCameraCapabilities(android.telecomm.CallCameraCapabilities);
     method public void changePeerDimensions(int, int);
     method public void handleCallSessionEvent(int);
-    method public abstract void onRequestCallDataUsage();
-    method public abstract void onRequestCameraCapabilities();
-    method public abstract void onSendSessionModifyRequest(android.telecomm.VideoCallProfile);
-    method public abstract void onSendSessionModifyResponse(android.telecomm.VideoCallProfile);
-    method public abstract void onSetCamera(java.lang.String);
-    method public abstract void onSetDeviceOrientation(int);
-    method public abstract void onSetDisplaySurface(android.view.Surface);
-    method public abstract void onSetPauseImage(java.lang.String);
-    method public abstract void onSetPreviewSurface(android.view.Surface);
-    method public abstract void onSetZoom(float);
+    method public void onRequestCallDataUsage();
+    method public void onRequestCameraCapabilities();
+    method public void onSendSessionModifyRequest(android.telecomm.VideoCallProfile);
+    method public void onSendSessionModifyResponse(android.telecomm.VideoCallProfile);
+    method public void onSetCamera(java.lang.String);
+    method public void onSetDeviceOrientation(int);
+    method public void onSetDisplaySurface(android.view.Surface);
+    method public void onSetPauseImage(java.lang.String);
+    method public void onSetPreviewSurface(android.view.Surface);
+    method public void onSetZoom(float);
     method public void receiveSessionModifyRequest(android.telecomm.VideoCallProfile);
     method public void receiveSessionModifyResponse(int, android.telecomm.VideoCallProfile, android.telecomm.VideoCallProfile);
   }
@@ -28916,22 +28946,25 @@
     method public int getCallCapabilities();
     method public java.lang.String getCallerDisplayName();
     method public int getCallerDisplayNamePresentation();
-    method public int getDisconnectCause();
-    method public java.lang.String getDisconnectMessage();
+    method public java.util.List<android.telecomm.RemoteConnection> getChildren();
+    method public int getDisconnectCauseCode();
+    method public java.lang.String getDisconnectCauseMessage();
     method public int getFailureCode();
     method public java.lang.String getFailureMessage();
     method public android.net.Uri getHandle();
     method public int getHandlePresentation();
+    method public android.telecomm.RemoteConnection getParent();
     method public int getState();
     method public android.telecomm.StatusHints getStatusHints();
     method public int getVideoState();
     method public void hold();
-    method public void playDtmf(char);
+    method public boolean isRequestingRingback();
+    method public void playDtmfTone(char);
     method public void postDialContinue(boolean);
     method public void reject();
     method public void removeListener(android.telecomm.RemoteConnection.Listener);
     method public void setAudioState(android.telecomm.CallAudioState);
-    method public void stopDtmf();
+    method public void stopDtmfTone();
     method public void swapWithBackgroundCall();
     method public void unhold();
   }
@@ -28941,9 +28974,12 @@
     method public void onAudioModeIsVoipChanged(android.telecomm.RemoteConnection, boolean);
     method public void onCallCapabilitiesChanged(android.telecomm.RemoteConnection, int);
     method public void onCallerDisplayNameChanged(android.telecomm.RemoteConnection, java.lang.String, int);
+    method public void onChildrenChanged(android.telecomm.RemoteConnection, java.util.List<android.telecomm.RemoteConnection>);
+    method public void onConferenceableConnectionsChanged(android.telecomm.RemoteConnection, java.util.List<android.telecomm.RemoteConnection>);
     method public void onDestroyed(android.telecomm.RemoteConnection);
     method public void onDisconnected(android.telecomm.RemoteConnection, int, java.lang.String);
     method public void onHandleChanged(android.telecomm.RemoteConnection, android.net.Uri, int);
+    method public void onParentChanged(android.telecomm.RemoteConnection, android.telecomm.RemoteConnection);
     method public void onPostDialWait(android.telecomm.RemoteConnection, java.lang.String);
     method public void onRequestingRingback(android.telecomm.RemoteConnection, boolean);
     method public void onStartActivityFromInCall(android.telecomm.RemoteConnection, android.app.PendingIntent);
@@ -29255,12 +29291,12 @@
 
   public class MessagingConfigurationManager {
     method public boolean getCarrierConfigBoolean(java.lang.String, boolean);
+    method public boolean getCarrierConfigBoolean(long, java.lang.String, boolean);
     method public int getCarrierConfigInt(java.lang.String, int);
+    method public int getCarrierConfigInt(long, java.lang.String, int);
     method public java.lang.String getCarrierConfigString(java.lang.String, java.lang.String);
+    method public java.lang.String getCarrierConfigString(long, java.lang.String, java.lang.String);
     method public static android.telephony.MessagingConfigurationManager getDefault();
-    method public void setCarrierConfigBoolean(java.lang.String, boolean);
-    method public void setCarrierConfigInt(java.lang.String, int);
-    method public void setCarrierConfigString(java.lang.String, java.lang.String);
     field public static final java.lang.String CONF_ALIAS_ENABLED = "aliasEnabled";
     field public static final java.lang.String CONF_ALIAS_MAX_CHARS = "aliasMaxChars";
     field public static final java.lang.String CONF_ALIAS_MIN_CHARS = "aliasMinChars";
@@ -29439,19 +29475,19 @@
     method public boolean deleteStoredConversation(long);
     method public boolean deleteStoredMessage(android.net.Uri);
     method public java.util.ArrayList<java.lang.String> divideMessage(java.lang.String);
-    method public void downloadMultimediaMessage(java.lang.String, android.app.PendingIntent);
-    method public void downloadMultimediaMessage(long, java.lang.String, android.app.PendingIntent);
+    method public void downloadMultimediaMessage(java.lang.String, android.content.ContentValues, android.app.PendingIntent);
+    method public void downloadMultimediaMessage(long, java.lang.String, android.content.ContentValues, android.app.PendingIntent);
     method public boolean getAutoPersisting();
     method public static android.telephony.SmsManager getDefault();
     method public android.net.Uri importMultimediaMessage(byte[], java.lang.String, long, boolean, boolean);
     method public android.net.Uri importTextMessage(java.lang.String, int, java.lang.String, long, boolean, boolean);
     method public void injectSmsPdu(byte[], java.lang.String, android.app.PendingIntent);
     method public void sendDataMessage(java.lang.String, java.lang.String, short, byte[], android.app.PendingIntent, android.app.PendingIntent);
-    method public void sendMultimediaMessage(byte[], java.lang.String, android.app.PendingIntent);
-    method public void sendMultimediaMessage(long, byte[], java.lang.String, android.app.PendingIntent);
+    method public void sendMultimediaMessage(byte[], java.lang.String, android.content.ContentValues, android.app.PendingIntent);
+    method public void sendMultimediaMessage(long, byte[], java.lang.String, android.content.ContentValues, android.app.PendingIntent);
     method public void sendMultipartTextMessage(java.lang.String, java.lang.String, java.util.ArrayList<java.lang.String>, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
-    method public void sendStoredMultimediaMessage(android.net.Uri, android.app.PendingIntent);
-    method public void sendStoredMultimediaMessage(long, android.net.Uri, android.app.PendingIntent);
+    method public void sendStoredMultimediaMessage(android.net.Uri, android.content.ContentValues, android.app.PendingIntent);
+    method public void sendStoredMultimediaMessage(long, android.net.Uri, android.content.ContentValues, android.app.PendingIntent);
     method public void sendStoredMultipartTextMessage(android.net.Uri, java.lang.String, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
     method public void sendStoredMultipartTextMessage(long, android.net.Uri, java.lang.String, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
     method public void sendStoredTextMessage(android.net.Uri, java.lang.String, android.app.PendingIntent, android.app.PendingIntent);
@@ -31745,7 +31781,7 @@
     field public static final int WEEKDAY_WEDNESDAY = 4; // 0x4
   }
 
-  public static abstract class TtsSpan.Builder {
+  public static class TtsSpan.Builder {
     ctor public TtsSpan.Builder(java.lang.String);
     method public android.text.style.TtsSpan build();
     method public C setIntArgument(java.lang.String, int);
@@ -32990,6 +33026,7 @@
     method public int getRotation();
     method public void getSize(android.graphics.Point);
     method public int getState();
+    method public float[] getSupportedRefreshRates();
     method public deprecated int getWidth();
     method public boolean isValid();
     field public static final int DEFAULT_DISPLAY = 0; // 0x0
@@ -34234,7 +34271,7 @@
     method public android.view.animation.Animation getAnimation();
     method public android.os.IBinder getApplicationWindowToken();
     method public android.graphics.drawable.Drawable getBackground();
-    method public android.content.res.ColorStateList getBackgroundTint();
+    method public android.content.res.ColorStateList getBackgroundTintList();
     method public android.graphics.PorterDuff.Mode getBackgroundTintMode();
     method public int getBaseline();
     method public final int getBottom();
@@ -34515,7 +34552,7 @@
     method public void setBackgroundColor(int);
     method public deprecated void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setBackgroundResource(int);
-    method public void setBackgroundTint(android.content.res.ColorStateList);
+    method public void setBackgroundTintList(android.content.res.ColorStateList);
     method public void setBackgroundTintMode(android.graphics.PorterDuff.Mode);
     method public final void setBottom(int);
     method public void setCameraDistance(float);
@@ -35633,6 +35670,7 @@
     field public float horizontalWeight;
     field public deprecated int memoryType;
     field public java.lang.String packageName;
+    field public float preferredRefreshRate;
     field public int rotationAnimation;
     field public float screenBrightness;
     field public int screenOrientation;
@@ -37569,13 +37607,13 @@
     method public boolean getSplitTrack();
     method public android.graphics.drawable.Drawable getThumb();
     method public int getThumbOffset();
-    method public android.content.res.ColorStateList getThumbTint();
+    method public android.content.res.ColorStateList getThumbTintList();
     method public android.graphics.PorterDuff.Mode getThumbTintMode();
     method public void setKeyProgressIncrement(int);
     method public void setSplitTrack(boolean);
     method public void setThumb(android.graphics.drawable.Drawable);
     method public void setThumbOffset(int);
-    method public void setThumbTint(android.content.res.ColorStateList);
+    method public void setThumbTintList(android.content.res.ColorStateList);
     method public void setThumbTintMode(android.graphics.PorterDuff.Mode);
   }
 
@@ -37962,12 +38000,12 @@
     ctor public CheckedTextView(android.content.Context, android.util.AttributeSet, int);
     ctor public CheckedTextView(android.content.Context, android.util.AttributeSet, int, int);
     method public android.graphics.drawable.Drawable getCheckMarkDrawable();
-    method public android.content.res.ColorStateList getCheckMarkTint();
+    method public android.content.res.ColorStateList getCheckMarkTintList();
     method public android.graphics.PorterDuff.Mode getCheckMarkTintMode();
     method public boolean isChecked();
     method public void setCheckMarkDrawable(int);
     method public void setCheckMarkDrawable(android.graphics.drawable.Drawable);
-    method public void setCheckMarkTint(android.content.res.ColorStateList);
+    method public void setCheckMarkTintList(android.content.res.ColorStateList);
     method public void setCheckMarkTintMode(android.graphics.PorterDuff.Mode);
     method public void setChecked(boolean);
     method public void toggle();
@@ -37997,12 +38035,12 @@
     ctor public CompoundButton(android.content.Context, android.util.AttributeSet);
     ctor public CompoundButton(android.content.Context, android.util.AttributeSet, int);
     ctor public CompoundButton(android.content.Context, android.util.AttributeSet, int, int);
-    method public android.content.res.ColorStateList getButtonTint();
+    method public android.content.res.ColorStateList getButtonTintList();
     method public android.graphics.PorterDuff.Mode getButtonTintMode();
     method public boolean isChecked();
     method public void setButtonDrawable(int);
     method public void setButtonDrawable(android.graphics.drawable.Drawable);
-    method public void setButtonTint(android.content.res.ColorStateList);
+    method public void setButtonTintList(android.content.res.ColorStateList);
     method public void setButtonTintMode(android.graphics.PorterDuff.Mode);
     method public void setChecked(boolean);
     method public void setOnCheckedChangeListener(android.widget.CompoundButton.OnCheckedChangeListener);
@@ -38266,13 +38304,13 @@
     method public deprecated boolean getConsiderGoneChildrenWhenMeasuring();
     method public android.graphics.drawable.Drawable getForeground();
     method public int getForegroundGravity();
-    method public android.content.res.ColorStateList getForegroundTint();
+    method public android.content.res.ColorStateList getForegroundTintList();
     method public android.graphics.PorterDuff.Mode getForegroundTintMode();
     method public boolean getMeasureAllChildren();
     method protected void onLayout(boolean, int, int, int, int);
     method public void setForeground(android.graphics.drawable.Drawable);
     method public void setForegroundGravity(int);
-    method public void setForegroundTint(android.content.res.ColorStateList);
+    method public void setForegroundTintList(android.content.res.ColorStateList);
     method public void setForegroundTintMode(android.graphics.PorterDuff.Mode);
     method public void setMeasureAllChildren(boolean);
   }
@@ -38479,11 +38517,11 @@
     method public android.graphics.drawable.Drawable getDrawable();
     method public int getImageAlpha();
     method public android.graphics.Matrix getImageMatrix();
+    method public android.content.res.ColorStateList getImageTintList();
+    method public android.graphics.PorterDuff.Mode getImageTintMode();
     method public int getMaxHeight();
     method public int getMaxWidth();
     method public android.widget.ImageView.ScaleType getScaleType();
-    method public android.content.res.ColorStateList getTint();
-    method public android.graphics.PorterDuff.Mode getTintMode();
     method public int[] onCreateDrawableState(int);
     method public void setAdjustViewBounds(boolean);
     method public deprecated void setAlpha(int);
@@ -38501,12 +38539,12 @@
     method public void setImageMatrix(android.graphics.Matrix);
     method public void setImageResource(int);
     method public void setImageState(int[], boolean);
+    method public void setImageTintList(android.content.res.ColorStateList);
+    method public void setImageTintMode(android.graphics.PorterDuff.Mode);
     method public void setImageURI(android.net.Uri);
     method public void setMaxHeight(int);
     method public void setMaxWidth(int);
     method public void setScaleType(android.widget.ImageView.ScaleType);
-    method public void setTint(android.content.res.ColorStateList);
-    method public void setTintMode(android.graphics.PorterDuff.Mode);
   }
 
   public static final class ImageView.ScaleType extends java.lang.Enum {
@@ -38881,18 +38919,18 @@
     ctor public ProgressBar(android.content.Context, android.util.AttributeSet, int);
     ctor public ProgressBar(android.content.Context, android.util.AttributeSet, int, int);
     method public android.graphics.drawable.Drawable getIndeterminateDrawable();
-    method public android.content.res.ColorStateList getIndeterminateTint();
+    method public android.content.res.ColorStateList getIndeterminateTintList();
     method public android.graphics.PorterDuff.Mode getIndeterminateTintMode();
     method public android.view.animation.Interpolator getInterpolator();
     method public synchronized int getMax();
     method public synchronized int getProgress();
-    method public android.content.res.ColorStateList getProgressBackgroundTint();
+    method public android.content.res.ColorStateList getProgressBackgroundTintList();
     method public android.graphics.PorterDuff.Mode getProgressBackgroundTintMode();
     method public android.graphics.drawable.Drawable getProgressDrawable();
-    method public android.content.res.ColorStateList getProgressTint();
+    method public android.content.res.ColorStateList getProgressTintList();
     method public android.graphics.PorterDuff.Mode getProgressTintMode();
     method public synchronized int getSecondaryProgress();
-    method public android.content.res.ColorStateList getSecondaryProgressTint();
+    method public android.content.res.ColorStateList getSecondaryProgressTintList();
     method public android.graphics.PorterDuff.Mode getSecondaryProgressTintMode();
     method public final synchronized void incrementProgressBy(int);
     method public final synchronized void incrementSecondaryProgressBy(int);
@@ -38902,20 +38940,20 @@
     method public synchronized void setIndeterminate(boolean);
     method public void setIndeterminateDrawable(android.graphics.drawable.Drawable);
     method public void setIndeterminateDrawableTiled(android.graphics.drawable.Drawable);
-    method public void setIndeterminateTint(android.content.res.ColorStateList);
+    method public void setIndeterminateTintList(android.content.res.ColorStateList);
     method public void setIndeterminateTintMode(android.graphics.PorterDuff.Mode);
     method public void setInterpolator(android.content.Context, int);
     method public void setInterpolator(android.view.animation.Interpolator);
     method public synchronized void setMax(int);
     method public synchronized void setProgress(int);
-    method public void setProgressBackgroundTint(android.content.res.ColorStateList);
+    method public void setProgressBackgroundTintList(android.content.res.ColorStateList);
     method public void setProgressBackgroundTintMode(android.graphics.PorterDuff.Mode);
     method public void setProgressDrawable(android.graphics.drawable.Drawable);
     method public void setProgressDrawableTiled(android.graphics.drawable.Drawable);
-    method public void setProgressTint(android.content.res.ColorStateList);
+    method public void setProgressTintList(android.content.res.ColorStateList);
     method public void setProgressTintMode(android.graphics.PorterDuff.Mode);
     method public synchronized void setSecondaryProgress(int);
-    method public void setSecondaryProgressTint(android.content.res.ColorStateList);
+    method public void setSecondaryProgressTintList(android.content.res.ColorStateList);
     method public void setSecondaryProgressTintMode(android.graphics.PorterDuff.Mode);
   }
 
@@ -43188,8 +43226,8 @@
     method public java.lang.annotation.Annotation[] getDeclaredAnnotations();
     method public boolean isAccessible();
     method public boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation>);
-    method public static void setAccessible(java.lang.reflect.AccessibleObject[], boolean);
     method public void setAccessible(boolean);
+    method public static void setAccessible(java.lang.reflect.AccessibleObject[], boolean);
   }
 
   public abstract interface AnnotatedElement {
diff --git a/cmds/appwidget/src/com/android/commands/appwidget/AppWidget.java b/cmds/appwidget/src/com/android/commands/appwidget/AppWidget.java
index dd45d39..5ea7352 100644
--- a/cmds/appwidget/src/com/android/commands/appwidget/AppWidget.java
+++ b/cmds/appwidget/src/com/android/commands/appwidget/AppWidget.java
@@ -150,7 +150,7 @@
             IBinder binder = ServiceManager.getService(Context.APPWIDGET_SERVICE);
             IAppWidgetService appWidgetService = IAppWidgetService.Stub.asInterface(binder);
             try {
-                appWidgetService.setBindAppWidgetPermission(mPackageName, mGranted, mUserId);
+                appWidgetService.setBindAppWidgetPermission(mPackageName, mUserId, mGranted);
             } catch (RemoteException re) {
                 re.printStackTrace();
             }
diff --git a/cmds/media/src/com/android/commands/media/Media.java b/cmds/media/src/com/android/commands/media/Media.java
index 7757b91..d9faf4c 100644
--- a/cmds/media/src/com/android/commands/media/Media.java
+++ b/cmds/media/src/com/android/commands/media/Media.java
@@ -191,7 +191,7 @@
         @Override
         public void onMetadataChanged(MediaMetadata metadata) {
             String mmString = metadata == null ? null : "title=" + metadata
-                    .getString(MediaMetadata.METADATA_KEY_TITLE);
+                    .getDescription();
             System.out.println("onMetadataChanged " + mmString);
         }
 
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 1f25dd0..c5e91e3 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -19,12 +19,13 @@
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
+import android.app.PackageDeleteObserver;
 import android.app.PackageInstallObserver;
 import android.content.ComponentName;
+import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageDataObserver;
-import android.content.pm.IPackageDeleteObserver;
 import android.content.pm.IPackageInstaller;
 import android.content.pm.IPackageManager;
 import android.content.pm.InstallSessionInfo;
@@ -760,7 +761,7 @@
         String extraPackage;
 
         @Override
-        public void packageInstalled(String name, Bundle extras, int status) {
+        public void onPackageInstalled(String name, int status, String msg, Bundle extras) {
             synchronized (this) {
                 finished = true;
                 result = status;
@@ -790,6 +791,11 @@
         }
 
         @Override
+        public void onUserActionRequired(Intent intent) {
+            setResult(false, "Unexepected user action required!");
+        }
+
+        @Override
         public void onSuccess() {
             setResult(true, null);
         }
@@ -1268,11 +1274,12 @@
         }
     }
 
-    class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
+    class LocalPackageDeleteObserver extends PackageDeleteObserver {
         boolean finished;
         boolean result;
 
-        public void packageDeleted(String packageName, int returnCode) {
+        @Override
+        public void onPackageDeleted(String name, int returnCode, String msg) {
             synchronized (this) {
                 finished = true;
                 result = returnCode == PackageManager.DELETE_SUCCEEDED;
@@ -1346,9 +1353,9 @@
     }
 
     private boolean deletePackage(String packageName, int flags, int userId) {
-        PackageDeleteObserver obs = new PackageDeleteObserver();
+        LocalPackageDeleteObserver obs = new LocalPackageDeleteObserver();
         try {
-            mInstaller.uninstall(packageName, flags, obs, userId);
+            mInstaller.uninstall(packageName, flags, obs.getBinder(), userId);
 
             synchronized (obs) {
                 while (!obs.finished) {
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 5262a5f..2a17fa6 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -25,4 +25,6 @@
     // Called by the power manager.
     public abstract void goingToSleep();
     public abstract void wakingUp();
+    public abstract int startIsolatedProcess(String entryPoint, String[] mainArgs,
+            String processName, String abiOverride, int uid, Runnable crashHandler);
 }
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index b3046b5..75af2df 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -196,7 +196,7 @@
     final protected ArrayList<View> mSharedElements = new ArrayList<View>();
     final protected ArrayList<String> mSharedElementNames = new ArrayList<String>();
     final protected ArrayList<View> mTransitioningViews = new ArrayList<View>();
-    final protected SharedElementListener mListener;
+    protected SharedElementListener mListener;
     protected ResultReceiver mResultReceiver;
     final private FixedEpicenterCallback mEpicenterCallback = new FixedEpicenterCallback();
     final protected boolean mIsReturning;
@@ -564,6 +564,7 @@
         mTransitioningViews.clear();
         mResultReceiver = null;
         mPendingTransition = null;
+        mListener = null;
     }
 
     protected long getFadeDuration() {
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index caadecb..a52186a 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -459,15 +459,15 @@
             null, //POST_NOTIFICATION
             null, //NEIGHBORING_CELLS
             null, //CALL_PHONE
-            null, //READ_SMS
-            null, //WRITE_SMS
-            null, //RECEIVE_SMS
-            null, //RECEIVE_EMERGECY_SMS
-            null, //RECEIVE_MMS
+            UserManager.DISALLOW_SMS, //READ_SMS
+            UserManager.DISALLOW_SMS, //WRITE_SMS
+            UserManager.DISALLOW_SMS, //RECEIVE_SMS
+            null, //RECEIVE_EMERGENCY_SMS
+            UserManager.DISALLOW_SMS, //RECEIVE_MMS
             null, //RECEIVE_WAP_PUSH
-            null, //SEND_SMS
-            null, //READ_ICC_SMS
-            null, //WRITE_ICC_SMS
+            UserManager.DISALLOW_SMS, //SEND_SMS
+            UserManager.DISALLOW_SMS, //READ_ICC_SMS
+            UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
             null, //WRITE_SETTINGS
             UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
             null, //ACCESS_NOTIFICATIONS
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 18ba8c4..84b5516 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -28,6 +28,7 @@
 import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageDeleteObserver2;
 import android.content.pm.IPackageInstallObserver;
 import android.content.pm.IPackageManager;
 import android.content.pm.IPackageMoveObserver;
@@ -1287,6 +1288,7 @@
             // Should never happen!
         }
     }
+
     @Override
     public void clearApplicationUserData(String packageName,
                                          IPackageDataObserver observer) {
@@ -1384,7 +1386,18 @@
     public void replacePreferredActivity(IntentFilter filter,
                                          int match, ComponentName[] set, ComponentName activity) {
         try {
-            mPM.replacePreferredActivity(filter, match, set, activity);
+            mPM.replacePreferredActivity(filter, match, set, activity, UserHandle.myUserId());
+        } catch (RemoteException e) {
+            // Should never happen!
+        }
+    }
+
+    @Override
+    public void replacePreferredActivityAsUser(IntentFilter filter,
+                                         int match, ComponentName[] set, ComponentName activity,
+                                         int userId) {
+        try {
+            mPM.replacePreferredActivity(filter, match, set, activity, userId);
         } catch (RemoteException e) {
             // Should never happen!
         }
@@ -1605,6 +1618,18 @@
     /**
      * @hide
      */
+    public void removeCrossProfileIntentsForPackage(String packageName,
+            int sourceUserId, int targetUserId) {
+        try {
+            mPM.removeCrossProfileIntentsForPackage(packageName, sourceUserId, targetUserId);
+        } catch (RemoteException e) {
+            // Should never happen!
+        }
+    }
+
+    /**
+     * @hide
+     */
     @Override
     public void clearCrossProfileIntentFilters(int sourceUserId) {
         try {
@@ -1638,7 +1663,8 @@
         }
 
         @Override
-        public void packageInstalled(String basePackageName, Bundle extras, int returnCode) {
+        public void onPackageInstalled(String basePackageName, int returnCode, String msg,
+                Bundle extras) {
             try {
                 mLegacy.packageInstalled(basePackageName, returnCode);
             } catch (RemoteException ignored) {
@@ -1646,6 +1672,22 @@
         }
     }
 
+    private static class LegacyPackageDeleteObserver extends PackageDeleteObserver {
+        private final IPackageDeleteObserver mLegacy;
+
+        public LegacyPackageDeleteObserver(IPackageDeleteObserver legacy) {
+            mLegacy = legacy;
+        }
+
+        @Override
+        public void onPackageDeleted(String basePackageName, int returnCode, String msg) {
+            try {
+                mLegacy.packageDeleted(basePackageName, returnCode);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
     private final ContextImpl mContext;
     private final IPackageManager mPM;
 
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 5f606a6..4cf8cb4 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -18,10 +18,12 @@
 
 import android.app.usage.IUsageStatsManager;
 import android.app.usage.UsageStatsManager;
+import android.appwidget.AppWidgetManager;
 import android.os.Build;
 
 import android.service.persistentdata.IPersistentDataBlockService;
 import android.service.persistentdata.PersistentDataBlockManager;
+import com.android.internal.appwidget.IAppWidgetService;
 import com.android.internal.policy.PolicyManager;
 import com.android.internal.util.Preconditions;
 
@@ -148,7 +150,6 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IAppOpsService;
-import com.android.internal.appwidget.IAppWidgetService.Stub;
 import com.android.internal.os.IDropBoxManagerService;
 import com.android.internal.telecomm.ITelecommService;
 
@@ -771,6 +772,12 @@
                     return new MediaProjectionManager(ctx);
                 }
         });
+
+        registerService(APPWIDGET_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                IBinder b = ServiceManager.getService(APPWIDGET_SERVICE);
+                return new AppWidgetManager(ctx, IAppWidgetService.Stub.asInterface(b));
+            }});
     }
 
     static ContextImpl getImpl(Context context) {
@@ -2100,6 +2107,25 @@
     }
 
     @Override
+    public Context createApplicationContext(ApplicationInfo application, int flags)
+            throws NameNotFoundException {
+        LoadedApk pi = mMainThread.getPackageInfo(application, mResources.getCompatibilityInfo(),
+                flags | CONTEXT_REGISTER_PACKAGE);
+        if (pi != null) {
+            final boolean restricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
+            ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
+                    new UserHandle(UserHandle.getUserId(application.uid)), restricted,
+                    mDisplay, mOverrideConfiguration);
+            if (c.mResources != null) {
+                return c;
+            }
+        }
+
+        throw new PackageManager.NameNotFoundException(
+                "Application package " + application.packageName + " not found");
+    }
+
+    @Override
     public Context createPackageContext(String packageName, int flags)
             throws NameNotFoundException {
         return createPackageContextAsUser(packageName, flags,
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 5347f03..772e132 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -454,7 +454,7 @@
      * Private non-Binder interfaces
      */
     /* package */ boolean testIsSystemReady();
-    
+
     /** Information you can retrieve about a particular application. */
     public static class ContentProviderHolder implements Parcelable {
         public final ProviderInfo info;
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index c7fdbed..5684a7a 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -32,6 +32,7 @@
 import android.media.session.MediaSession;
 import android.net.Uri;
 import android.os.BadParcelableException;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -247,7 +248,6 @@
 
 
     /**
-     * @hide
      * A medium-format version of {@link #contentView}, providing the Notification an
      * opportunity to add action buttons to contentView. At its discretion, the system UI may
      * choose to show this as a heads-up notification, which will pop up so the user can see
@@ -814,6 +814,13 @@
     public static final String EXTRA_COMPACT_ACTIONS = "android.compactActions";
 
     /**
+     * {@link #extras} key: the user that built the notification.
+     *
+     * @hide
+     */
+    public static final String EXTRA_ORIGINATING_USERID = "android.originatingUserId";
+
+    /**
      * Value for {@link #EXTRA_AS_HEADS_UP} that indicates this notification should not be
      * displayed in the heads up space.
      *
@@ -1700,28 +1707,6 @@
         }
     }
 
-    /** {@hide} */
-    public void setUser(UserHandle user) {
-        if (user.getIdentifier() == UserHandle.USER_ALL) {
-            user = UserHandle.OWNER;
-        }
-        if (tickerView != null) {
-            tickerView.setUser(user);
-        }
-        if (contentView != null) {
-            contentView.setUser(user);
-        }
-        if (bigContentView != null) {
-            bigContentView.setUser(user);
-        }
-        if (headsUpContentView != null) {
-            headsUpContentView.setUser(user);
-        }
-        if (publicVersion != null) {
-            publicVersion.setUser(user);
-        }
-    }
-
     /**
      * @hide
      */
@@ -1862,6 +1847,10 @@
         private ArrayList<String> mPeople;
         private int mColor = COLOR_DEFAULT;
 
+        /**
+         * The user that built the notification originally.
+         */
+        private int mOriginatingUserId;
 
         /**
          * Contains extras related to rebuilding during the build phase.
@@ -1911,7 +1900,8 @@
             mPriority = PRIORITY_DEFAULT;
             mPeople = new ArrayList<String>();
 
-            mColorUtil = NotificationColorUtil.getInstance();
+            mColorUtil = context.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.L ?
+                    NotificationColorUtil.getInstance() : null;
         }
 
         /**
@@ -2569,8 +2559,10 @@
         }
 
         private Bitmap getProfileBadge() {
+            // Note: This assumes that the current user can read the profile badge of the
+            // originating user.
             UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-            Drawable badge = userManager.getBadgeForUser(android.os.Process.myUserHandle());
+            Drawable badge = userManager.getBadgeForUser(new UserHandle(mOriginatingUserId), 0);
             if (badge == null) {
                 return null;
             }
@@ -2585,7 +2577,8 @@
 
         private RemoteViews applyStandardTemplate(int resId, boolean fitIn1U) {
             Bitmap profileIcon = getProfileBadge();
-            RemoteViews contentView = new BuilderRemoteViews(mContext.getPackageName(), resId);
+            RemoteViews contentView = new BuilderRemoteViews(mContext.getPackageName(),
+                    mOriginatingUserId, resId);
             boolean showLine3 = false;
             boolean showLine2 = false;
 
@@ -2918,6 +2911,7 @@
          */
         public void populateExtras(Bundle extras) {
             // Store original information used in the construction of this object
+            extras.putInt(EXTRA_ORIGINATING_USERID, mOriginatingUserId);
             extras.putString(EXTRA_REBUILD_CONTEXT_PACKAGE, mContext.getPackageName());
             extras.putCharSequence(EXTRA_TITLE, mContentTitle);
             extras.putCharSequence(EXTRA_TEXT, mContentText);
@@ -3145,6 +3139,7 @@
 
             // Extras.
             Bundle extras = n.extras;
+            mOriginatingUserId = extras.getInt(EXTRA_ORIGINATING_USERID);
             mContentTitle = extras.getCharSequence(EXTRA_TITLE);
             mContentText = extras.getCharSequence(EXTRA_TEXT);
             mSubText = extras.getCharSequence(EXTRA_SUB_TEXT);
@@ -3177,6 +3172,8 @@
          * object.
          */
         public Notification build() {
+            mOriginatingUserId = mContext.getUserId();
+
             Notification n = buildUnstyled();
 
             if (mStyle != null) {
@@ -4580,8 +4577,8 @@
             super(parcel);
         }
 
-        public BuilderRemoteViews(String packageName, int layoutId) {
-            super(packageName, layoutId);
+        public BuilderRemoteViews(String packageName, int userId, int layoutId) {
+            super(packageName, userId, layoutId);
         }
 
         @Override
diff --git a/core/java/android/app/PackageDeleteObserver.java b/core/java/android/app/PackageDeleteObserver.java
new file mode 100644
index 0000000..9b83ec1
--- /dev/null
+++ b/core/java/android/app/PackageDeleteObserver.java
@@ -0,0 +1,46 @@
+/*
+ * 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.app;
+
+import android.content.Intent;
+import android.content.pm.IPackageDeleteObserver2;
+
+/** {@hide} */
+public class PackageDeleteObserver {
+    private final IPackageDeleteObserver2.Stub mBinder = new IPackageDeleteObserver2.Stub() {
+        @Override
+        public void onUserActionRequired(Intent intent) {
+            PackageDeleteObserver.this.onUserActionRequired(intent);
+        }
+
+        @Override
+        public void onPackageDeleted(String basePackageName, int returnCode, String msg) {
+            PackageDeleteObserver.this.onPackageDeleted(basePackageName, returnCode, msg);
+        }
+    };
+
+    /** {@hide} */
+    public IPackageDeleteObserver2 getBinder() {
+        return mBinder;
+    }
+
+    public void onUserActionRequired(Intent intent) {
+    }
+
+    public void onPackageDeleted(String basePackageName, int returnCode, String msg) {
+    }
+}
diff --git a/core/java/android/app/PackageInstallObserver.java b/core/java/android/app/PackageInstallObserver.java
index 1b2504e..ff28679 100644
--- a/core/java/android/app/PackageInstallObserver.java
+++ b/core/java/android/app/PackageInstallObserver.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.content.Intent;
 import android.content.pm.IPackageInstallObserver2;
 import android.os.Bundle;
 
@@ -23,9 +24,15 @@
 public class PackageInstallObserver {
     private final IPackageInstallObserver2.Stub mBinder = new IPackageInstallObserver2.Stub() {
         @Override
-        public void packageInstalled(String basePackageName, Bundle extras, int returnCode,
-                String msg) {
-            PackageInstallObserver.this.packageInstalled(basePackageName, extras, returnCode, msg);
+        public void onUserActionRequired(Intent intent) {
+            PackageInstallObserver.this.onUserActionRequired(intent);
+        }
+
+        @Override
+        public void onPackageInstalled(String basePackageName, int returnCode,
+                String msg, Bundle extras) {
+            PackageInstallObserver.this.onPackageInstalled(basePackageName, returnCode, msg,
+                    extras);
         }
     };
 
@@ -34,6 +41,9 @@
         return mBinder;
     }
 
+    public void onUserActionRequired(Intent intent) {
+    }
+
     /**
      * This method will be called to report the result of the package
      * installation attempt.
@@ -49,11 +59,7 @@
      *            basic outcome
      * @hide
      */
-    public void packageInstalled(String basePackageName, Bundle extras, int returnCode) {
-    }
-
-    public void packageInstalled(String basePackageName, Bundle extras, int returnCode,
-            String msg) {
-        packageInstalled(basePackageName, extras, returnCode);
+    public void onPackageInstalled(String basePackageName, int returnCode, String msg,
+            Bundle extras) {
     }
 }
diff --git a/core/java/android/app/PackageUninstallObserver.java b/core/java/android/app/PackageUninstallObserver.java
deleted file mode 100644
index 83fc380..0000000
--- a/core/java/android/app/PackageUninstallObserver.java
+++ /dev/null
@@ -1,37 +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.app;
-
-import android.content.pm.IPackageDeleteObserver;
-
-/** {@hide} */
-public class PackageUninstallObserver {
-    private final IPackageDeleteObserver.Stub mBinder = new IPackageDeleteObserver.Stub() {
-        @Override
-        public void packageDeleted(String basePackageName, int returnCode) {
-            PackageUninstallObserver.this.onUninstallFinished(basePackageName, returnCode);
-        }
-    };
-
-    /** {@hide} */
-    public IPackageDeleteObserver getBinder() {
-        return mBinder;
-    }
-
-    public void onUninstallFinished(String basePackageName, int returnCode) {
-    }
-}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index e28f00c..ca6b1e8 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -20,6 +20,7 @@
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
 import android.app.Activity;
+import android.app.admin.IDevicePolicyManager;
 import android.content.AbstractRestrictionsProvider;
 import android.content.ComponentName;
 import android.content.Context;
@@ -28,8 +29,6 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.content.RestrictionsManager;
-import android.media.AudioService;
 import android.net.ProxyInfo;
 import android.os.Bundle;
 import android.os.Handler;
@@ -40,7 +39,6 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
-import android.service.trust.TrustAgentService;
 import android.util.Log;
 
 import com.android.org.conscrypt.TrustedCertificateStore;
@@ -55,6 +53,7 @@
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
@@ -3079,4 +3078,85 @@
         }
         return false;
     }
+
+    /**
+     * Called by the profile owner to enable widget providers from a given package
+     * to be available in the parent profile. As a result the user will be able to
+     * add widgets from the white-listed package running under the profile to a widget
+     * host which runs under the device owner, for example the home screen. Note that
+     * a package may have zero or more provider components, where each component
+     * provides a different widget type.
+     * <p>
+     * <strong>Note:</strong> By default no widget provider package is white-listed.
+     * </p>
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param packageName The package from which widget providers are white-listed.
+     * @return Whether the package was added.
+     *
+     * @see #removeCrossProfileWidgetProvider(android.content.ComponentName, String)
+     * @see #getCrossProfileWidgetProviders(android.content.ComponentName)
+     */
+    public boolean addCrossProfileWidgetProvider(ComponentName admin, String packageName) {
+        if (mService != null) {
+            try {
+                return mService.addCrossProfileWidgetProvider(admin, packageName);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Error calling addCrossProfileWidgetProvider", re);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Called by the profile owner to disable widget providers from a given package
+     * to be available in the parent profile. For this method to take effect the
+     * package should have been added via {@link #addCrossProfileWidgetProvider(
+     * android.content.ComponentName, String)}.
+     * <p>
+     * <strong>Note:</strong> By default no widget provider package is white-listed.
+     * </p>
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param packageName The package from which widget providers are no longer
+     *     white-listed.
+     * @return Whether the package was removed.
+     *
+     * @see #addCrossProfileWidgetProvider(android.content.ComponentName, String)
+     * @see #getCrossProfileWidgetProviders(android.content.ComponentName)
+     */
+    public boolean removeCrossProfileWidgetProvider(ComponentName admin, String packageName) {
+        if (mService != null) {
+            try {
+                return mService.removeCrossProfileWidgetProvider(admin, packageName);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Error calling removeCrossProfileWidgetProvider", re);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Called by the profile owner to query providers from which packages are
+     * available in the parent profile.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @return The white-listed package list.
+     *
+     * @see #addCrossProfileWidgetProvider(android.content.ComponentName, String)
+     * @see #removeCrossProfileWidgetProvider(android.content.ComponentName, String)
+     */
+    public List<String> getCrossProfileWidgetProviders(ComponentName admin) {
+        if (mService != null) {
+            try {
+                List<String> providers = mService.getCrossProfileWidgetProviders(admin);
+                if (providers != null) {
+                    return providers;
+                }
+            } catch (RemoteException re) {
+                Log.w(TAG, "Error calling getCrossProfileWidgetProviders", re);
+            }
+        }
+        return Collections.emptyList();
+    }
 }
diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java
new file mode 100644
index 0000000..edd8199
--- /dev/null
+++ b/core/java/android/app/admin/DevicePolicyManagerInternal.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 android.app.admin;
+
+import java.util.List;
+
+/**
+ * Device policy manager local system service interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class DevicePolicyManagerInternal {
+
+    /**
+     * Gets the packages whose widget providers are white-listed to be
+     * available in the parent user.
+     *
+     * @param profileId The profile id.
+     * @return The list of packages if such or empty list if there are
+     *    no white-listed packages or the profile id is not a managed
+     *    profile.
+     */
+    public abstract List<String> getCrossProfileWidgetProviders(int profileId);
+}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 6ce737a..8954c0d 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -175,4 +175,7 @@
     void setTrustAgentFeaturesEnabled(in ComponentName admin, in ComponentName agent, in List<String> features, int userId);
     List<String> getTrustAgentFeaturesEnabled(in ComponentName admin, in ComponentName agent, int userId);
 
+    boolean addCrossProfileWidgetProvider(in ComponentName admin, String packageName);
+    boolean removeCrossProfileWidgetProvider(in ComponentName admin, String packageName);
+    List<String> getCrossProfileWidgetProviders(in ComponentName admin);
 }
diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java
index 84d3835..66a6eb6 100644
--- a/core/java/android/appwidget/AppWidgetHost.java
+++ b/core/java/android/appwidget/AppWidgetHost.java
@@ -19,7 +19,11 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
@@ -28,7 +32,6 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.UserHandle;
 import android.util.DisplayMetrics;
 import android.util.TypedValue;
 import android.widget.RemoteViews;
@@ -53,7 +56,6 @@
     private DisplayMetrics mDisplayMetrics;
 
     Context mContext;
-    String mPackageName;
     Handler mHandler;
     int mHostId;
     Callbacks mCallbacks = new Callbacks();
@@ -61,32 +63,30 @@
     private OnClickHandler mOnClickHandler;
 
     class Callbacks extends IAppWidgetHost.Stub {
-        public void updateAppWidget(int appWidgetId, RemoteViews views, int userId) {
+        public void updateAppWidget(int appWidgetId, RemoteViews views) {
             if (isLocalBinder() && views != null) {
                 views = views.clone();
-                views.setUser(new UserHandle(userId));
             }
-            Message msg = mHandler.obtainMessage(HANDLE_UPDATE, appWidgetId, userId, views);
+            Message msg = mHandler.obtainMessage(HANDLE_UPDATE, appWidgetId, 0, views);
             msg.sendToTarget();
         }
 
-        public void providerChanged(int appWidgetId, AppWidgetProviderInfo info, int userId) {
+        public void providerChanged(int appWidgetId, AppWidgetProviderInfo info) {
             if (isLocalBinder() && info != null) {
                 info = info.clone();
             }
             Message msg = mHandler.obtainMessage(HANDLE_PROVIDER_CHANGED,
-                    appWidgetId, userId, info);
+                    appWidgetId, 0, info);
             msg.sendToTarget();
         }
 
-        public void providersChanged(int userId) {
-            Message msg = mHandler.obtainMessage(HANDLE_PROVIDERS_CHANGED, userId, 0);
-            msg.sendToTarget();
+        public void providersChanged() {
+            mHandler.obtainMessage(HANDLE_PROVIDERS_CHANGED).sendToTarget();
         }
 
-        public void viewDataChanged(int appWidgetId, int viewId, int userId) {
+        public void viewDataChanged(int appWidgetId, int viewId) {
             Message msg = mHandler.obtainMessage(HANDLE_VIEW_DATA_CHANGED,
-                    appWidgetId, viewId, userId);
+                    appWidgetId, viewId);
             msg.sendToTarget();
         }
     }
@@ -99,7 +99,7 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case HANDLE_UPDATE: {
-                    updateAppWidgetView(msg.arg1, (RemoteViews)msg.obj, msg.arg2);
+                    updateAppWidgetView(msg.arg1, (RemoteViews)msg.obj);
                     break;
                 }
                 case HANDLE_PROVIDER_CHANGED: {
@@ -111,7 +111,7 @@
                     break;
                 }
                 case HANDLE_VIEW_DATA_CHANGED: {
-                    viewDataChanged(msg.arg1, msg.arg2, (Integer) msg.obj);
+                    viewDataChanged(msg.arg1, msg.arg2);
                     break;
                 }
             }
@@ -151,25 +151,17 @@
     public void startListening() {
         int[] updatedIds;
         ArrayList<RemoteViews> updatedViews = new ArrayList<RemoteViews>();
-
-        final int userId = mContext.getUserId();
         try {
-            if (mPackageName == null) {
-                mPackageName = mContext.getPackageName();
-            }
-            updatedIds = sService.startListening(
-                    mCallbacks, mPackageName, mHostId, updatedViews, userId);
+            updatedIds = sService.startListening(mCallbacks, mContext.getPackageName(), mHostId,
+                    updatedViews);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
         }
 
         final int N = updatedIds.length;
-        for (int i=0; i<N; i++) {
-            if (updatedViews.get(i) != null) {
-                updatedViews.get(i).setUser(new UserHandle(userId));
-            }
-            updateAppWidgetView(updatedIds[i], updatedViews.get(i), userId);
+        for (int i = 0; i < N; i++) {
+            updateAppWidgetView(updatedIds[i], updatedViews.get(i));
         }
     }
 
@@ -179,7 +171,7 @@
      */
     public void stopListening() {
         try {
-            sService.stopListening(mHostId, mContext.getUserId());
+            sService.stopListening(mContext.getPackageName(), mHostId);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -197,10 +189,7 @@
      */
     public int allocateAppWidgetId() {
         try {
-            if (mPackageName == null) {
-                mPackageName = mContext.getPackageName();
-            }
-            return sService.allocateAppWidgetId(mPackageName, mHostId, mContext.getUserId());
+            return sService.allocateAppWidgetId(mContext.getPackageName(), mHostId);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -208,18 +197,39 @@
     }
 
     /**
-     * Get a appWidgetId for a host in the given package.
+     * Starts an app widget provider configure activity for result on behalf of the caller.
+     * Use this method if the provider is in another profile as you are not allowed to start
+     * an activity in another profile. The provided intent must have action {@link
+     * AppWidgetManager#ACTION_APPWIDGET_CONFIGURE}. The widget id must be specified by
+     * the {@link AppWidgetManager#EXTRA_APPWIDGET_ID} extra. The provider configure
+     * activity must be specified as the component name of the intent via {@link
+     * Intent#setComponent(android.content.ComponentName)}. The user profile under which
+     * the provider operates is specified via the {@link
+     * AppWidgetManager#EXTRA_APPWIDGET_PROVIDER_PROFILE} extra. If a user profile is
+     * not provided, the current user is used. Finally, you can optionally provide a
+     * request code that is returned in {@link Activity#onActivityResult(int, int,
+     * android.content.Intent)}.
      *
-     * @return a appWidgetId
-     * @hide
+     * @param activity The activity from which to start the configure one.
+     * @param intent Properly populated intent for launching the configuration activity.
+     * @param requestCode Optional request code retuned with the result.
+     *
+     * @throws android.content.ActivityNotFoundException If the activity is not found.
+     *
+     * @see AppWidgetProviderInfo#getProfile()
      */
-    public static int allocateAppWidgetIdForPackage(int hostId, int userId, String packageName) {
-        checkCallerIsSystem();
+    public final void startAppWidgetConfigureActivityForResult(Activity activity, Intent intent,
+            int requestCode) {
         try {
-            if (sService == null) {
-                bindService();
+            IntentSender intentSender = sService.createAppWidgetConfigIntentSender(
+                    mContext.getPackageName(), intent);
+            if (intentSender != null) {
+                activity.startIntentSenderForResult(intentSender, requestCode, null, 0, 0, 0);
+            } else {
+                throw new ActivityNotFoundException();
             }
-            return sService.allocateAppWidgetId(packageName, hostId, userId);
+        } catch (IntentSender.SendIntentException e) {
+            throw new ActivityNotFoundException();
         } catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
         }
@@ -235,20 +245,12 @@
             if (sService == null) {
                 bindService();
             }
-            return sService.getAppWidgetIdsForHost(mHostId, mContext.getUserId());
+            return sService.getAppWidgetIdsForHost(mContext.getPackageName(), mHostId);
         } catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
         }
     }
 
-    private static void checkCallerIsSystem() {
-        int uid = Process.myUid();
-        if (UserHandle.getAppId(uid) == Process.SYSTEM_UID || uid == 0) {
-            return;
-        }
-        throw new SecurityException("Disallowed call for uid " + uid);
-    }
-
     private boolean isLocalBinder() {
         return Process.myPid() == Binder.getCallingPid();
     }
@@ -260,7 +262,7 @@
         synchronized (mViews) {
             mViews.remove(appWidgetId);
             try {
-                sService.deleteAppWidgetId(appWidgetId, mContext.getUserId());
+                sService.deleteAppWidgetId(mContext.getPackageName(), appWidgetId);
             }
             catch (RemoteException e) {
                 throw new RuntimeException("system server dead?", e);
@@ -269,22 +271,6 @@
     }
 
     /**
-     * Stop listening to changes for this AppWidget.
-     * @hide
-     */
-    public static void deleteAppWidgetIdForSystem(int appWidgetId, int userId) {
-        checkCallerIsSystem();
-        try {
-            if (sService == null) {
-                bindService();
-            }
-            sService.deleteAppWidgetId(appWidgetId, userId);
-        } catch (RemoteException e) {
-            throw new RuntimeException("system server dead?", e);
-        }
-    }
-
-    /**
      * Remove all records about this host from the AppWidget manager.
      * <ul>
      *   <li>Call this when initializing your database, as it might be because of a data wipe.</li>
@@ -294,7 +280,7 @@
      */
     public void deleteHost() {
         try {
-            sService.deleteHost(mHostId, mContext.getUserId());
+            sService.deleteHost(mContext.getPackageName(), mHostId);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -310,16 +296,8 @@
      * </ul>
      */
     public static void deleteAllHosts() {
-        deleteAllHosts(UserHandle.myUserId());
-    }
-
-    /**
-     * Private method containing a userId
-     * @hide
-     */
-    public static void deleteAllHosts(int userId) {
         try {
-            sService.deleteAllHosts(userId);
+            sService.deleteAllHosts();
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -332,9 +310,7 @@
      */
     public final AppWidgetHostView createView(Context context, int appWidgetId,
             AppWidgetProviderInfo appWidget) {
-        final int userId = mContext.getUserId();
         AppWidgetHostView view = onCreateView(mContext, appWidgetId, appWidget);
-        view.setUserId(userId);
         view.setOnClickHandler(mOnClickHandler);
         view.setAppWidget(appWidgetId, appWidget);
         synchronized (mViews) {
@@ -342,10 +318,7 @@
         }
         RemoteViews views;
         try {
-            views = sService.getAppWidgetViews(appWidgetId, userId);
-            if (views != null) {
-                views.setUser(new UserHandle(mContext.getUserId()));
-            }
+            views = sService.getAppWidgetViews(mContext.getPackageName(), appWidgetId);
         } catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
         }
@@ -397,7 +370,7 @@
         // Does nothing
     }
 
-    void updateAppWidgetView(int appWidgetId, RemoteViews views, int userId) {
+    void updateAppWidgetView(int appWidgetId, RemoteViews views) {
         AppWidgetHostView v;
         synchronized (mViews) {
             v = mViews.get(appWidgetId);
@@ -407,7 +380,7 @@
         }
     }
 
-    void viewDataChanged(int appWidgetId, int viewId, int userId) {
+    void viewDataChanged(int appWidgetId, int viewId) {
         AppWidgetHostView v;
         synchronized (mViews) {
             v = mViews.get(appWidgetId);
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index 700bba8..1ff476e 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -87,7 +87,6 @@
     Bitmap mOld;
     Paint mOldPaint = new Paint();
     private OnClickHandler mOnClickHandler;
-    private UserHandle mUser;
 
     /**
      * Create a host view.  Uses default fade animations.
@@ -115,17 +114,11 @@
     public AppWidgetHostView(Context context, int animationIn, int animationOut) {
         super(context);
         mContext = context;
-        mUser = Process.myUserHandle();
         // We want to segregate the view ids within AppWidgets to prevent
         // problems when those ids collide with view ids in the AppWidgetHost.
         setIsRootNamespace(true);
     }
 
-    /** @hide */
-    public void setUserId(int userId) {
-        mUser = new UserHandle(userId);
-    }
-
     /**
      * Pass the given handler to RemoteViews when updating this widget. Unless this
      * is done immediatly after construction, a call to {@link #updateAppWidget(RemoteViews)}
@@ -380,7 +373,7 @@
         } else {
             // Prepare a local reference to the remote Context so we're ready to
             // inflate any requested LayoutParams.
-            mRemoteContext = getRemoteContext(remoteViews);
+            mRemoteContext = getRemoteContext();
             int layoutId = remoteViews.getLayoutId();
 
             // If our stale view has been prepared to match active, and the new
@@ -466,17 +459,14 @@
      * Build a {@link Context} cloned into another package name, usually for the
      * purposes of reading remote resources.
      */
-    private Context getRemoteContext(RemoteViews views) {
-        // Bail if missing package name
-        final String packageName = views.getPackage();
-        if (packageName == null) return mContext;
-
+    private Context getRemoteContext() {
         try {
             // Return if cloned successfully, otherwise default
-            return mContext.createPackageContextAsUser(packageName, Context.CONTEXT_RESTRICTED,
-                    mUser);
+            return mContext.createApplicationContext(
+                    mInfo.providerInfo.applicationInfo,
+                    Context.CONTEXT_RESTRICTED);
         } catch (NameNotFoundException e) {
-            Log.e(TAG, "Package name " + packageName + " not found");
+            Log.e(TAG, "Package name " +  mInfo.providerInfo.packageName + " not found");
             return mContext;
         }
     }
@@ -548,8 +538,7 @@
 
         try {
             if (mInfo != null) {
-                Context theirContext = mContext.createPackageContextAsUser(
-                        mInfo.provider.getPackageName(), Context.CONTEXT_RESTRICTED, mUser);
+                Context theirContext = getRemoteContext();
                 mRemoteContext = theirContext;
                 LayoutInflater inflater = (LayoutInflater)
                         theirContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -572,8 +561,6 @@
             } else {
                 Log.w(TAG, "can't inflate defaultView because mInfo is missing");
             }
-        } catch (PackageManager.NameNotFoundException e) {
-            exception = e;
         } catch (RuntimeException e) {
             exception = e;
         }
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index e5bf7d0..e5d1d95 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -21,8 +21,8 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.os.Process;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.util.DisplayMetrics;
 import android.util.TypedValue;
@@ -30,9 +30,8 @@
 
 import com.android.internal.appwidget.IAppWidgetService;
 
-import java.lang.ref.WeakReference;
+import java.util.Collections;
 import java.util.List;
-import java.util.WeakHashMap;
 
 /**
  * Updates AppWidget state; gets information about installed AppWidget providers and other
@@ -45,7 +44,6 @@
  * </div>
  */
 public class AppWidgetManager {
-    static final String TAG = "AppWidgetManager";
 
     /**
      * Activity action to launch from your {@link AppWidgetHost} activity when you want to
@@ -72,9 +70,9 @@
      * <p>
      * When you receive the result from the AppWidget pick activity, if the resultCode is
      * {@link android.app.Activity#RESULT_OK}, an AppWidget has been selected.  You should then
-     * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its configuration
-     * activity.  If {@link android.app.Activity#RESULT_CANCELED} is returned, you should delete
-     * the appWidgetId.
+     * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its
+     * configuration activity.  If {@link android.app.Activity#RESULT_CANCELED} is returned, you
+     * should delete the appWidgetId.
      *
      * @see #ACTION_APPWIDGET_CONFIGURE
      */
@@ -103,6 +101,12 @@
      *     <td>The BroadcastReceiver that will be the AppWidget provider for this AppWidget.
      *     </td>
      *  </tr>
+     *  <tr>
+     *     <td>{@link #EXTRA_APPWIDGET_PROVIDER_PROFILE}</td>
+     *     <td>An optional handle to a user profile under which runs the provider
+     *     for this AppWidget.
+     *     </td>
+     *  </tr>
      * </table>
      *
      * <p>
@@ -119,8 +123,7 @@
      * {@link android.app.Activity#RESULT_OK}, the AppWidget has been bound.  You should then
      * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its
      * configuration activity.  If {@link android.app.Activity#RESULT_CANCELED} is returned, you
-     * should delete
-     * the appWidgetId.
+     * should delete the appWidgetId.
      *
      * @see #ACTION_APPWIDGET_CONFIGURE
      *
@@ -130,7 +133,8 @@
     /**
      * Sent when it is time to configure your AppWidget while it is being added to a host.
      * This action is not sent as a broadcast to the AppWidget provider, but as a startActivity
-     * to the activity specified in the {@link AppWidgetProviderInfo AppWidgetProviderInfo meta-data}.
+     * to the activity specified in the {@link AppWidgetProviderInfo AppWidgetProviderInfo
+     * meta-data}.
      *
      * <p>
      * The intent will contain the following extras:
@@ -145,7 +149,8 @@
      * {@link android.app.Activity#setResult Activity.setResult()}, the AppWidget will be added,
      * and you will receive an {@link #ACTION_APPWIDGET_UPDATE} broadcast for this AppWidget.
      * If you return {@link android.app.Activity#RESULT_CANCELED}, the host will cancel the add
-     * and not display this AppWidget, and you will receive a {@link #ACTION_APPWIDGET_DELETED} broadcast.
+     * and not display this AppWidget, and you will receive a {@link #ACTION_APPWIDGET_DELETED}
+     * broadcast.
      */
     public static final String ACTION_APPWIDGET_CONFIGURE = "android.appwidget.action.APPWIDGET_CONFIGURE";
 
@@ -188,7 +193,9 @@
 
     /**
      * An intent extra which points to a bundle of extra information for a particular widget id.
-     * In particular this bundle can contain EXTRA_APPWIDGET_WIDTH and EXTRA_APPWIDGET_HEIGHT.
+     * In particular this bundle can contain {@link #OPTION_APPWIDGET_MIN_WIDTH},
+     * {@link #OPTION_APPWIDGET_MIN_HEIGHT}, {@link #OPTION_APPWIDGET_MAX_WIDTH},
+     * {@link #OPTION_APPWIDGET_MAX_HEIGHT}.
      */
     public static final String EXTRA_APPWIDGET_OPTIONS = "appWidgetOptions";
 
@@ -203,11 +210,19 @@
     /**
      * An intent extra that contains the component name of a AppWidget provider.
      * <p>
-     * The value will be an ComponentName.
+     * The value will be an {@link android.content.ComponentName}.
      */
     public static final String EXTRA_APPWIDGET_PROVIDER = "appWidgetProvider";
 
     /**
+     * An intent extra that contains the user handle of the profile under
+     * which an AppWidget provider is registered.
+     * <p>
+     * The value will be a {@link android.os.UserHandle}.
+     */
+    public static final String EXTRA_APPWIDGET_PROVIDER_PROFILE = "appWidgetProviderProfile";
+
+    /**
      * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of
      * {@link AppWidgetProviderInfo} objects to mix in to the list of AppWidgets that are
      * installed.  (This is how the launcher shows the search widget).
@@ -295,12 +310,12 @@
     public static final String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED";
 
     /**
-     * Sent when an instance of an AppWidget is removed from the last host.
+     * Sent when the last AppWidget of this provider is removed from the last host.
      *
      * <p class="note">This is a protected intent that can only be sent
      * by the system.
      *
-     * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context)
+     * @see AppWidgetProvider#onEnabled AppWidgetProvider.onDisabled(Context context)
      */
     public static final String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED";
 
@@ -403,46 +418,36 @@
      */
     public static final String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider";
 
-    static WeakHashMap<Context, WeakReference<AppWidgetManager>> sManagerCache =
-        new WeakHashMap<Context, WeakReference<AppWidgetManager>>();
-    static IAppWidgetService sService;
+    private final String mPackageName;
 
-    Context mContext;
+    private final IAppWidgetService mService;
 
-    private DisplayMetrics mDisplayMetrics;
+    private final DisplayMetrics mDisplayMetrics;
 
     /**
      * Get the AppWidgetManager instance to use for the supplied {@link android.content.Context
      * Context} object.
      */
     public static AppWidgetManager getInstance(Context context) {
-        synchronized (sManagerCache) {
-            if (sService == null) {
-                IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE);
-                sService = IAppWidgetService.Stub.asInterface(b);
-            }
-
-            WeakReference<AppWidgetManager> ref = sManagerCache.get(context);
-            AppWidgetManager result = null;
-            if (ref != null) {
-                result = ref.get();
-            }
-            if (result == null) {
-                result = new AppWidgetManager(context);
-                sManagerCache.put(context, new WeakReference<AppWidgetManager>(result));
-            }
-            return result;
-        }
+        return (AppWidgetManager) context.getSystemService(Context.APPWIDGET_SERVICE);
     }
 
-    private AppWidgetManager(Context context) {
-        mContext = context;
+    /**
+     * Creates a new instance.
+     *
+     * @param context The current context in which to operate.
+     * @param service The backing system service.
+     * @hide
+     */
+    public AppWidgetManager(Context context, IAppWidgetService service) {
+        mPackageName = context.getPackageName();
+        mService = service;
         mDisplayMetrics = context.getResources().getDisplayMetrics();
     }
 
     /**
      * Set the RemoteViews to use for the specified appWidgetIds.
-     *
+     * <p>
      * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should
      * contain a complete representation of the widget. For performing partial widget updates, see
      * {@link #partiallyUpdateAppWidget(int[], RemoteViews)}.
@@ -456,12 +461,15 @@
      * The total Bitmap memory used by the RemoteViews object cannot exceed that required to
      * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes.
      *
-     * @param appWidgetIds     The AppWidget instances for which to set the RemoteViews.
-     * @param views         The RemoteViews object to show.
+     * @param appWidgetIds The AppWidget instances for which to set the RemoteViews.
+     * @param views The RemoteViews object to show.
      */
     public void updateAppWidget(int[] appWidgetIds, RemoteViews views) {
+        if (mService == null) {
+            return;
+        }
         try {
-            sService.updateAppWidgetIds(appWidgetIds, views, mContext.getUserId());
+            mService.updateAppWidgetIds(mPackageName, appWidgetIds, views);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -470,18 +478,21 @@
 
     /**
      * Update the extras for a given widget instance.
-     *
+     * <p>
      * The extras can be used to embed additional information about this widget to be accessed
      * by the associated widget's AppWidgetProvider.
      *
      * @see #getAppWidgetOptions(int)
      *
-     * @param appWidgetId    The AppWidget instances for which to set the RemoteViews.
-     * @param options         The options to associate with this widget
+     * @param appWidgetId The AppWidget instances for which to set the RemoteViews.
+     * @param options The options to associate with this widget
      */
     public void updateAppWidgetOptions(int appWidgetId, Bundle options) {
+        if (mService == null) {
+            return;
+        }
         try {
-            sService.updateAppWidgetOptions(appWidgetId, options, mContext.getUserId());
+            mService.updateAppWidgetOptions(mPackageName, appWidgetId, options);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -490,18 +501,21 @@
 
     /**
      * Get the extras associated with a given widget instance.
-     *
+     * <p>
      * The extras can be used to embed additional information about this widget to be accessed
      * by the associated widget's AppWidgetProvider.
      *
      * @see #updateAppWidgetOptions(int, Bundle)
      *
-     * @param appWidgetId     The AppWidget instances for which to set the RemoteViews.
-     * @return                The options associated with the given widget instance.
+     * @param appWidgetId The AppWidget instances for which to set the RemoteViews.
+     * @return The options associated with the given widget instance.
      */
     public Bundle getAppWidgetOptions(int appWidgetId) {
+        if (mService == null) {
+            return Bundle.EMPTY;
+        }
         try {
-            return sService.getAppWidgetOptions(appWidgetId, mContext.getUserId());
+            return mService.getAppWidgetOptions(mPackageName, appWidgetId);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -510,7 +524,7 @@
 
     /**
      * Set the RemoteViews to use for the specified appWidgetId.
-     *
+     * <p>
      * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should
      * contain a complete representation of the widget. For performing partial widget updates, see
      * {@link #partiallyUpdateAppWidget(int, RemoteViews)}.
@@ -528,12 +542,15 @@
      * @param views         The RemoteViews object to show.
      */
     public void updateAppWidget(int appWidgetId, RemoteViews views) {
+        if (mService == null) {
+            return;
+        }
         updateAppWidget(new int[] { appWidgetId }, views);
     }
 
     /**
      * Perform an incremental update or command on the widget(s) specified by appWidgetIds.
-     *
+     * <p>
      * This update  differs from {@link #updateAppWidget(int[], RemoteViews)} in that the
      * RemoteViews object which is passed is understood to be an incomplete representation of the
      * widget, and hence does not replace the cached representation of the widget. As of API
@@ -556,8 +573,11 @@
      * @param views            The RemoteViews object containing the incremental update / command.
      */
     public void partiallyUpdateAppWidget(int[] appWidgetIds, RemoteViews views) {
+        if (mService == null) {
+            return;
+        }
         try {
-            sService.partiallyUpdateAppWidgetIds(appWidgetIds, views, mContext.getUserId());
+            mService.partiallyUpdateAppWidgetIds(mPackageName, appWidgetIds, views);
         } catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
         }
@@ -565,7 +585,7 @@
 
     /**
      * Perform an incremental update or command on the widget specified by appWidgetId.
-     *
+     * <p>
      * This update  differs from {@link #updateAppWidget(int, RemoteViews)} in that the RemoteViews
      * object which is passed is understood to be an incomplete representation of the widget, and
      * hence is not cached by the AppWidgetService. Note that because these updates are not cached,
@@ -588,6 +608,9 @@
      * @param views            The RemoteViews object containing the incremental update / command.
      */
     public void partiallyUpdateAppWidget(int appWidgetId, RemoteViews views) {
+        if (mService == null) {
+            return;
+        }
         partiallyUpdateAppWidget(new int[] { appWidgetId }, views);
     }
 
@@ -605,8 +628,11 @@
      * @param views         The RemoteViews object to show.
      */
     public void updateAppWidget(ComponentName provider, RemoteViews views) {
+        if (mService == null) {
+            return;
+        }
         try {
-            sService.updateAppWidgetProvider(provider, views, mContext.getUserId());
+            mService.updateAppWidgetProvider(provider, views);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -621,8 +647,11 @@
      * @param viewId        The collection view id.
      */
     public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId) {
+        if (mService == null) {
+            return;
+        }
         try {
-            sService.notifyAppWidgetViewDataChanged(appWidgetIds, viewId, mContext.getUserId());
+            mService.notifyAppWidgetViewDataChanged(mPackageName, appWidgetIds, viewId);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -637,37 +666,106 @@
      * @param viewId       The collection view id.
      */
     public void notifyAppWidgetViewDataChanged(int appWidgetId, int viewId) {
+        if (mService == null) {
+            return;
+        }
         notifyAppWidgetViewDataChanged(new int[] { appWidgetId }, viewId);
     }
 
     /**
+     * Gets the AppWidget providers for the given user profiles. User profiles can only
+     * be the current user or a profile of the current user. For example, the current
+     * user may have a corporate profile. In this case the parent user profile has a
+     * child profile, the corporate one.
+     *
+     * @param profiles The profiles for which to get providers. Passing null is equivaled
+     *         to passing only the current user handle.
+     * @return The intalled providers.
+     *
+     * @see android.os.Process#myUserHandle()
+     * @see android.os.UserManager#getUserProfiles()
+     */
+    public List<AppWidgetProviderInfo> getInstalledProvidersForProfiles(UserHandle[] profiles) {
+        if (mService == null) {
+            return Collections.emptyList();
+        }
+        return getInstalledProvidersForProfiles(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
+                profiles);
+    }
+
+    /**
      * Return a list of the AppWidget providers that are currently installed.
      */
     public List<AppWidgetProviderInfo> getInstalledProviders() {
-        return getInstalledProviders(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN);
+        if (mService == null) {
+            return Collections.emptyList();
+        }
+        return getInstalledProvidersForProfiles(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
+                null);
     }
 
     /**
-     * Return a list of the AppWidget providers that are currently installed.
+     * Gets the AppWidget providers for the current user.
      *
      * @param categoryFilter Will only return providers which register as any of the specified
      *        specified categories. See {@link AppWidgetProviderInfo#widgetCategory}.
+     * @return The intalled providers.
+     *
+     * @see android.os.Process#myUserHandle()
+     * @see android.os.UserManager#getUserProfiles()
+     *
      * @hide
      */
     public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter) {
+        if (mService == null) {
+            return Collections.emptyList();
+        }
+        return getInstalledProvidersForProfiles(categoryFilter, null);
+    }
+
+    /**
+     * Gets the AppWidget providers for the given user profiles. User profiles can only
+     * be the current user or a profile of the current user. For example, the current
+     * user may have a corporate profile. In this case the parent user profile has a
+     * child profile, the corporate one.
+     *
+     * @param categoryFilter Will only return providers which register as any of the specified
+     *        specified categories. See {@link AppWidgetProviderInfo#widgetCategory}.
+     * @param profiles Child profiles of the current user which to be queried. The user
+     *        is itself also a profile. If null, the providers only for the current user
+     *        are returned.
+     * @return The intalled providers.
+     *
+     * @see android.os.Process#myUserHandle()
+     * @see android.os.UserManager#getUserProfiles()
+     *
+     * @hide
+     */
+    public List<AppWidgetProviderInfo> getInstalledProvidersForProfiles(int categoryFilter,
+            UserHandle[] profiles) {
+        if (mService == null) {
+            return Collections.emptyList();
+        }
+
+        int[] profileIds = null;
+
+        if (profiles != null) {
+            final int profileCount = profiles.length;
+            profileIds = new int[profileCount];
+            for (int i = 0; i < profileCount; i++) {
+                profileIds[i] = profiles[i].getIdentifier();
+            }
+        }
+
         try {
-            List<AppWidgetProviderInfo> providers = sService.getInstalledProviders(categoryFilter,
-                    mContext.getUserId());
+            List<AppWidgetProviderInfo> providers = mService.getInstalledProviders(categoryFilter,
+                    profileIds);
+            if (providers == null) {
+                return Collections.emptyList();
+            }
             for (AppWidgetProviderInfo info : providers) {
                 // Converting complex to dp.
-                info.minWidth =
-                        TypedValue.complexToDimensionPixelSize(info.minWidth, mDisplayMetrics);
-                info.minHeight =
-                        TypedValue.complexToDimensionPixelSize(info.minHeight, mDisplayMetrics);
-                info.minResizeWidth =
-                    TypedValue.complexToDimensionPixelSize(info.minResizeWidth, mDisplayMetrics);
-                info.minResizeHeight =
-                    TypedValue.complexToDimensionPixelSize(info.minResizeHeight, mDisplayMetrics);
+                convertSizesToPixels(info);
             }
             return providers;
         }
@@ -683,19 +781,14 @@
      * you don't have access to that appWidgetId, null is returned.
      */
     public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) {
+        if (mService == null) {
+            return null;
+        }
         try {
-            AppWidgetProviderInfo info = sService.getAppWidgetInfo(appWidgetId,
-                    mContext.getUserId());
+            AppWidgetProviderInfo info = mService.getAppWidgetInfo(mPackageName, appWidgetId);
             if (info != null) {
                 // Converting complex to dp.
-                info.minWidth =
-                        TypedValue.complexToDimensionPixelSize(info.minWidth, mDisplayMetrics);
-                info.minHeight =
-                        TypedValue.complexToDimensionPixelSize(info.minHeight, mDisplayMetrics);
-                info.minResizeWidth =
-                    TypedValue.complexToDimensionPixelSize(info.minResizeWidth, mDisplayMetrics);
-                info.minResizeHeight =
-                    TypedValue.complexToDimensionPixelSize(info.minResizeHeight, mDisplayMetrics);
+                convertSizesToPixels(info);
             }
             return info;
         }
@@ -717,12 +810,10 @@
      * @hide
      */
     public void bindAppWidgetId(int appWidgetId, ComponentName provider) {
-        try {
-            sService.bindAppWidgetId(appWidgetId, provider, null, mContext.getUserId());
+        if (mService == null) {
+            return;
         }
-        catch (RemoteException e) {
-            throw new RuntimeException("system server dead?", e);
-        }
+        bindAppWidgetId(appWidgetId, provider, null);
     }
 
     /**
@@ -741,12 +832,10 @@
      * @hide
      */
     public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options) {
-        try {
-            sService.bindAppWidgetId(appWidgetId, provider, options, mContext.getUserId());
+        if (mService == null) {
+            return;
         }
-        catch (RemoteException e) {
-            throw new RuntimeException("system server dead?", e);
-        }
+        bindAppWidgetIdIfAllowed(appWidgetId, Process.myUserHandle(), provider, options);
     }
 
     /**
@@ -757,22 +846,16 @@
      *         method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to
      *         bind
      *
-     * @param appWidgetId     The AppWidget instance for which to set the RemoteViews.
+     * @param appWidgetId   The AppWidget id under which to bind the provider.
      * @param provider      The {@link android.content.BroadcastReceiver} that will be the AppWidget
      *                      provider for this AppWidget.
      * @return true if this component has permission to bind the AppWidget
      */
     public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider) {
-        if (mContext == null) {
+        if (mService == null) {
             return false;
         }
-        try {
-            return sService.bindAppWidgetIdIfAllowed(
-                    mContext.getPackageName(), appWidgetId, provider, null, mContext.getUserId());
-        }
-        catch (RemoteException e) {
-            throw new RuntimeException("system server dead?", e);
-        }
+        return bindAppWidgetIdIfAllowed(appWidgetId, UserHandle.myUserId(), provider, null);
     }
 
     /**
@@ -783,7 +866,7 @@
      *         method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to
      *         bind
      *
-     * @param appWidgetId     The AppWidget instance for which to set the RemoteViews.
+     * @param appWidgetId The AppWidget id under which to bind the provider.
      * @param provider      The {@link android.content.BroadcastReceiver} that will be the AppWidget
      *                      provider for this AppWidget.
      * @param options       Bundle containing options for the AppWidget. See also
@@ -793,12 +876,52 @@
      */
     public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider,
             Bundle options) {
-        if (mContext == null) {
+        if (mService == null) {
+            return false;
+        }
+        return bindAppWidgetIdIfAllowed(appWidgetId, UserHandle.myUserId(), provider, options);
+    }
+
+    /**
+     * Set the provider for a given appWidgetId if the caller has a permission.
+     * <p>
+     * <strong>Note:</strong> You need the {@link android.Manifest.permission#BIND_APPWIDGET}
+     * permission or the user must have enabled binding widgets always for your component.
+     * Should be used by apps that host widgets. If this method returns false, call {@link
+     * #ACTION_APPWIDGET_BIND} to request permission to bind.
+     * </p>
+     *
+     * @param appWidgetId The AppWidget id under which to bind the provider.
+     * @param user The user id in which the provider resides.
+     * @param provider The component name of the provider.
+     * @param options An optional Bundle containing options for the AppWidget.
+     *
+     * @return true if this component has permission to bind the AppWidget
+     */
+    public boolean bindAppWidgetIdIfAllowed(int appWidgetId, UserHandle user,
+            ComponentName provider, Bundle options) {
+        if (mService == null) {
+            return false;
+        }
+        return bindAppWidgetIdIfAllowed(appWidgetId, user.getIdentifier(), provider, options);
+    }
+
+    /**
+     * Query if a given package was granted permission by the user to bind app widgets
+     *
+     * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
+     *
+     * @param packageName The package for which the permission is being queried
+     * @param userId The user id of the user under which the package runs.
+     * @return true if the package was granted permission by the user to bind app widgets
+     * @hide
+     */
+    public boolean hasBindAppWidgetPermission(String packageName, int userId) {
+        if (mService == null) {
             return false;
         }
         try {
-            return sService.bindAppWidgetIdIfAllowed(mContext.getPackageName(), appWidgetId,
-                    provider, options, mContext.getUserId());
+            return mService.hasBindAppWidgetPermission(packageName, userId);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -815,8 +938,11 @@
      * @hide
      */
     public boolean hasBindAppWidgetPermission(String packageName) {
+        if (mService == null) {
+            return false;
+        }
         try {
-            return sService.hasBindAppWidgetPermission(packageName, mContext.getUserId());
+            return mService.hasBindAppWidgetPermission(packageName, UserHandle.myUserId());
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -828,13 +954,35 @@
      *
      * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
      *
-     * @param provider        The package whose permission is being changed
-     * @param permission      Whether to give the package permission to bind widgets
+     * @param packageName The package whose permission is being changed
+     * @param permission Whether to give the package permission to bind widgets
+     *
      * @hide
      */
     public void setBindAppWidgetPermission(String packageName, boolean permission) {
+        if (mService == null) {
+            return;
+        }
+        setBindAppWidgetPermission(packageName, UserHandle.myUserId(), permission);
+    }
+
+    /**
+     * Changes any user-granted permission for the given package to bind app widgets
+     *
+     * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
+     *
+     * @param packageName The package whose permission is being changed
+     * @param userId The user under which the package is running.
+     * @param permission Whether to give the package permission to bind widgets
+     *
+     * @hide
+     */
+    public void setBindAppWidgetPermission(String packageName, int userId, boolean permission) {
+        if (mService == null) {
+            return;
+        }
         try {
-            sService.setBindAppWidgetPermission(packageName, permission, mContext.getUserId());
+            mService.setBindAppWidgetPermission(packageName, userId, permission);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -847,18 +995,20 @@
      * The appWidgetId specified must already be bound to the calling AppWidgetHost via
      * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}.
      *
+     * @param packageName   The package from which the binding is requested.
      * @param appWidgetId   The AppWidget instance for which to bind the RemoteViewsService.
      * @param intent        The intent of the service which will be providing the data to the
      *                      RemoteViewsAdapter.
      * @param connection    The callback interface to be notified when a connection is made or lost.
-     * @param userHandle    The user to bind to.
      * @hide
      */
-    public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection,
-            UserHandle userHandle) {
+    public void bindRemoteViewsService(String packageName, int appWidgetId, Intent intent,
+            IBinder connection) {
+        if (mService == null) {
+            return;
+        }
         try {
-            sService.bindRemoteViewsService(appWidgetId, intent, connection,
-                    userHandle.getIdentifier());
+            mService.bindRemoteViewsService(packageName, appWidgetId, intent, connection);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -871,15 +1021,18 @@
      * The appWidgetId specified muse already be bound to the calling AppWidgetHost via
      * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}.
      *
+     * @param packageName   The package from which the binding is requested.
      * @param appWidgetId   The AppWidget instance for which to bind the RemoteViewsService.
      * @param intent        The intent of the service which will be providing the data to the
      *                      RemoteViewsAdapter.
-     * @param userHandle    The user to unbind from.
      * @hide
      */
-    public void unbindRemoteViewsService(int appWidgetId, Intent intent, UserHandle userHandle) {
+    public void unbindRemoteViewsService(String packageName, int appWidgetId, Intent intent) {
+        if (mService == null) {
+            return;
+        }
         try {
-            sService.unbindRemoteViewsService(appWidgetId, intent, userHandle.getIdentifier());
+            mService.unbindRemoteViewsService(packageName, appWidgetId, intent);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -894,12 +1047,40 @@
      *            AppWidget provider to find appWidgetIds for.
      */
     public int[] getAppWidgetIds(ComponentName provider) {
+        if (mService == null) {
+            return new int[0];
+        }
         try {
-            return sService.getAppWidgetIds(provider, mContext.getUserId());
+            return mService.getAppWidgetIds(provider);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
         }
     }
-}
 
+    private boolean bindAppWidgetIdIfAllowed(int appWidgetId, int profileId,
+            ComponentName provider, Bundle options) {
+        if (mService == null) {
+            return false;
+        }
+        try {
+            return mService.bindAppWidgetId(mPackageName, appWidgetId,
+                    profileId, provider, options);
+        }
+        catch (RemoteException e) {
+            throw new RuntimeException("system server dead?", e);
+        }
+    }
+
+    private void convertSizesToPixels(AppWidgetProviderInfo info) {
+        // Converting complex to dp.
+        info.minWidth = TypedValue.complexToDimensionPixelSize(info.minWidth,
+                mDisplayMetrics);
+        info.minHeight = TypedValue.complexToDimensionPixelSize(info.minHeight,
+                mDisplayMetrics);
+        info.minResizeWidth = TypedValue.complexToDimensionPixelSize(info.minResizeWidth,
+                mDisplayMetrics);
+        info.minResizeHeight = TypedValue.complexToDimensionPixelSize(info.minResizeHeight,
+                mDisplayMetrics);
+    }
+}
diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
index 8b9c7f0..6835368 100644
--- a/core/java/android/appwidget/AppWidgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -16,9 +16,15 @@
 
 package android.appwidget;
 
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.content.ComponentName;
+import android.os.UserHandle;
 
 /**
  * Describes the meta data for an installed AppWidget provider.  The fields in this class
@@ -145,16 +151,15 @@
     public ComponentName configure;
 
     /**
-     * The label to display to the user in the AppWidget picker.  If not supplied in the
-     * xml, the application label will be used.
+     * The label to display to the user in the AppWidget picker.
      *
-     * <p>This field corresponds to the <code>android:label</code> attribute in
-     * the <code>&lt;receiver&gt;</code> element in the AndroidManifest.xml file.
+     * @deprecated Use {@link #loadLabel(android.content.pm.PackageManager)}.
      */
+    @Deprecated
     public String label;
 
     /**
-     * The icon to display for this AppWidget in the AppWidget picker.  If not supplied in the
+     * The icon to display for this AppWidget in the AppWidget picker. If not supplied in the
      * xml, the application icon will be used.
      *
      * <p>This field corresponds to the <code>android:icon</code> attribute in
@@ -200,12 +205,17 @@
      */
     public int widgetCategory;
 
+    /** @hide */
+    public ActivityInfo providerInfo;
+
     public AppWidgetProviderInfo() {
+
     }
 
     /**
      * Unflatten the AppWidgetProviderInfo from a parcel.
      */
+    @SuppressWarnings("deprecation")
     public AppWidgetProviderInfo(Parcel in) {
         if (0 != in.readInt()) {
             this.provider = new ComponentName(in);
@@ -226,8 +236,74 @@
         this.autoAdvanceViewId = in.readInt();
         this.resizeMode = in.readInt();
         this.widgetCategory = in.readInt();
+        this.providerInfo = in.readParcelable(null);
     }
 
+    /**
+     * Loads the localized label to display to the user in the AppWidget picker.
+     *
+     * @param packageManager Package manager instance for loading resources.
+     * @return The label for the current locale.
+     */
+    public final String loadLabel(PackageManager packageManager) {
+        CharSequence label = providerInfo.loadLabel(packageManager);
+        if (label != null) {
+            return label.toString().trim();
+        }
+        return null;
+    }
+
+    /**
+     * Loads the icon to display for this AppWidget in the AppWidget picker. If not
+     * supplied in the xml, the application icon will be used. A client can optionally
+     * provide a desired density such as {@link android.util.DisplayMetrics#DENSITY_LOW}
+     * {@link android.util.DisplayMetrics#DENSITY_MEDIUM}, etc. If no density is
+     * provided, the density of the current display will be used.
+     * <p>
+     * The loaded icon corresponds to the <code>android:icon</code> attribute in
+     * the <code>&lt;receiver&gt;</code> element in the AndroidManifest.xml file.
+     * </p>
+     *
+     * @param context Context for accessing resources.
+     * @param density The optional desired density as per
+     *         {@link android.util.DisplayMetrics#densityDpi}.
+     * @return The provider icon.
+     */
+    public final Drawable loadIcon(Context context, int density) {
+        return loadDrawable(context, density, providerInfo.getIconResource());
+    }
+
+    /**
+     * Loads a preview of what the AppWidget will look like after it's configured.
+     * If not supplied, the AppWidget's icon will be used. A client can optionally
+     * provide a desired deinsity such as {@link android.util.DisplayMetrics#DENSITY_LOW}
+     * {@link android.util.DisplayMetrics#DENSITY_MEDIUM}, etc. If no density is
+     * provided, the density of the current display will be used.
+     * <p>
+     * The loaded image corresponds to the <code>android:previewImage</code> attribute
+     * in the <code>&lt;receiver&gt;</code> element in the AndroidManifest.xml file.
+     * </p>
+     *
+     * @param context Context for accessing resources.
+     * @param density The optional desired density as per
+     *         {@link android.util.DisplayMetrics#densityDpi}.
+     * @return The widget preview image.
+     */
+    public final Drawable loadPreviewImage(Context context, int density) {
+        return loadDrawable(context, density, previewImage);
+    }
+
+    /**
+     * Gets the user profile in which the provider resides.
+     *
+     * @return The hosting user profile.
+     */
+    public final UserHandle getProfile() {
+        return new UserHandle(UserHandle.getUserId(providerInfo.applicationInfo.uid));
+    }
+
+    @Override
+    @SuppressWarnings("deprecation")
     public void writeToParcel(android.os.Parcel out, int flags) {
         if (this.provider != null) {
             out.writeInt(1);
@@ -254,9 +330,11 @@
         out.writeInt(this.autoAdvanceViewId);
         out.writeInt(this.resizeMode);
         out.writeInt(this.widgetCategory);
+        out.writeParcelable(this.providerInfo, flags);
     }
 
     @Override
+    @SuppressWarnings("deprecation")
     public AppWidgetProviderInfo clone() {
         AppWidgetProviderInfo that = new AppWidgetProviderInfo();
         that.provider = this.provider == null ? null : this.provider.clone();
@@ -273,7 +351,8 @@
         that.previewImage = this.previewImage;
         that.autoAdvanceViewId = this.autoAdvanceViewId;
         that.resizeMode = this.resizeMode;
-        that.widgetCategory  = this.widgetCategory;
+        that.widgetCategory = this.widgetCategory;
+        that.providerInfo = this.providerInfo;
         return that;
     }
 
@@ -281,6 +360,22 @@
         return 0;
     }
 
+    private Drawable loadDrawable(Context context, int density, int resourceId) {
+        try {
+            Resources resources = context.getPackageManager().getResourcesForApplication(
+                    providerInfo.applicationInfo);
+            if (resourceId > 0) {
+                if (density <= 0) {
+                    density = context.getResources().getDisplayMetrics().densityDpi;
+                }
+                return resources.getDrawableForDensity(resourceId, density);
+            }
+        } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
+            /* ignore */
+        }
+        return providerInfo.loadIcon(context.getPackageManager());
+    }
+
     /**
      * Parcelable.Creator that instantiates AppWidgetProviderInfo objects
      */
@@ -299,6 +394,6 @@
     };
 
     public String toString() {
-        return "AppWidgetProviderInfo(provider=" + this.provider + ")";
+        return "AppWidgetProviderInfo(" + getProfile() + '/' + provider + ')';
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index a94bc41..860512b 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -760,7 +760,38 @@
             return false;
         }
         try {
-            return sService.createBond(this);
+            return sService.createBond(this, TRANSPORT_AUTO);
+        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        return false;
+    }
+
+    /**
+     * Start the bonding (pairing) process with the remote device using the
+     * specified transport.
+     *
+     * <p>This is an asynchronous call, it will return immediately. Register
+     * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
+     * the bonding process completes, and its result.
+     * <p>Android system services will handle the necessary user interactions
+     * to confirm and complete the bonding process.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
+     *
+     * @param transport The transport to use for the pairing procedure.
+     * @return false on immediate error, true if bonding will begin
+     * @throws IllegalArgumentException if an invalid transport was specified
+     * @hide
+     */
+    public boolean createBond(int transport) {
+        if (sService == null) {
+            Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device");
+            return false;
+        }
+        if (TRANSPORT_AUTO > transport || transport > TRANSPORT_LE)
+        {
+            throw new IllegalArgumentException(transport + " is not a valid Bluetooth transport");
+        }
+        try {
+            return sService.createBond(this, transport);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 1fe43ec..59d7956 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -16,7 +16,6 @@
 
 package android.bluetooth;
 
-import android.bluetooth.le.ScanResult;
 import android.content.Context;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
@@ -130,10 +129,10 @@
     /*package*/ static final int AUTHENTICATION_MITM = 2;
 
     /**
-     * Bluetooth GATT interface callbacks
+     * Bluetooth GATT callbacks. Overrides the default BluetoothGattCallback implementation.
      */
     private final IBluetoothGattCallback mBluetoothGattCallback =
-        new IBluetoothGattCallback.Stub() {
+        new BluetoothGattCallbackWrapper() {
             /**
              * Application interface registered - app is ready to go
              * @hide
@@ -198,14 +197,6 @@
             }
 
             /**
-             * Callback reporting an LE scan result.
-             * @hide
-             */
-            public void onScanResult(String address, int rssi, byte[] advData) {
-                // no op
-            }
-
-            /**
              * A new GATT service has been discovered.
              * The service is added to the internal list and the search
              * continues.
@@ -600,23 +591,6 @@
             }
 
             /**
-             * Advertise state change callback
-             * @hide
-             */
-            public void onAdvertiseStateChange(int state, int status) {
-                if (DBG) Log.d(TAG, "onAdvertiseStateChange() - state = "
-                        + state + " status=" + status);
-            }
-
-            /**
-             * @hide
-             */
-            @Override
-            public void onMultiAdvertiseCallback(int status) {
-                // no op.
-            }
-
-            /**
              * Callback invoked when the MTU for a given connection changes
              * @hide
              */
@@ -647,20 +621,6 @@
                     Log.w(TAG, "Unhandled exception in callback", ex);
                 }
             }
-
-            @Override
-            public void onBatchScanResults(List<ScanResult> results) {
-                // no op
-            }
-
-            /**
-             * @hide
-             */
-            @Override
-            public void onFoundOrLost(boolean onFound, String address, int rssi,
-                    byte[] advData) {
-                // no op.
-            }
         };
 
     /*package*/ BluetoothGatt(Context context, IBluetoothGatt iGatt, BluetoothDevice device,
diff --git a/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java b/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java
new file mode 100644
index 0000000..0eb9d21
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java
@@ -0,0 +1,131 @@
+/*
+ * 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.bluetooth;
+
+import android.bluetooth.le.AdvertiseSettings;
+import android.bluetooth.le.ScanResult;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+
+import java.util.List;
+
+/**
+ * Wrapper class for default implementation of IBluetoothGattCallback.
+ *
+ * @hide
+ */
+public class BluetoothGattCallbackWrapper extends IBluetoothGattCallback.Stub {
+
+    @Override
+    public void onClientRegistered(int status, int clientIf) throws RemoteException {
+    }
+
+    @Override
+    public void onClientConnectionState(int status, int clientIf, boolean connected, String address)
+            throws RemoteException {
+    }
+
+    @Override
+    public void onScanResult(ScanResult scanResult) throws RemoteException {
+    }
+
+    @Override
+    public void onBatchScanResults(List<ScanResult> batchResults) throws RemoteException {
+    }
+
+    @Override
+    public void onGetService(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid)
+            throws RemoteException {
+    }
+
+    @Override
+    public void onGetIncludedService(String address, int srvcType, int srvcInstId,
+            ParcelUuid srvcUuid, int inclSrvcType, int inclSrvcInstId, ParcelUuid inclSrvcUuid)
+            throws RemoteException {
+    }
+
+    @Override
+    public void onGetCharacteristic(String address, int srvcType, int srvcInstId,
+            ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, int charProps)
+            throws RemoteException {
+    }
+
+    @Override
+    public void onGetDescriptor(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid,
+            int charInstId, ParcelUuid charUuid, int descrInstId, ParcelUuid descrUuid)
+            throws RemoteException {
+    }
+
+    @Override
+    public void onSearchComplete(String address, int status) throws RemoteException {
+    }
+
+    @Override
+    public void onCharacteristicRead(String address, int status, int srvcType, int srvcInstId,
+            ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, byte[] value)
+            throws RemoteException {
+    }
+
+    @Override
+    public void onCharacteristicWrite(String address, int status, int srvcType, int srvcInstId,
+            ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid) throws RemoteException {
+    }
+
+    @Override
+    public void onExecuteWrite(String address, int status) throws RemoteException {
+    }
+
+    @Override
+    public void onDescriptorRead(String address, int status, int srvcType, int srvcInstId,
+            ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, int descrInstId,
+            ParcelUuid descrUuid, byte[] value) throws RemoteException {
+    }
+
+    @Override
+    public void onDescriptorWrite(String address, int status, int srvcType, int srvcInstId,
+            ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, int descrInstId,
+            ParcelUuid descrUuid) throws RemoteException {
+    }
+
+    @Override
+    public void onNotify(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid,
+            int charInstId, ParcelUuid charUuid, byte[] value) throws RemoteException {
+    }
+
+    @Override
+    public void onReadRemoteRssi(String address, int rssi, int status) throws RemoteException {
+    }
+
+    @Override
+    public void onMultiAdvertiseCallback(int status, boolean isStart,
+            AdvertiseSettings advertiseSettings) throws RemoteException {
+    }
+
+    @Override
+    public void onConfigureMTU(String address, int mtu, int status) throws RemoteException {
+    }
+
+    @Override
+    public void onConnectionCongested(String address, boolean congested) throws RemoteException {
+    }
+
+    @Override
+    public void onFoundOrLost(boolean onFound, String address, int rssi, byte[] advData)
+            throws RemoteException {
+    }
+
+}
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index ca55803..19c600c 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -55,7 +55,7 @@
     int getProfileConnectionState(int profile);
 
     BluetoothDevice[] getBondedDevices();
-    boolean createBond(in BluetoothDevice device);
+    boolean createBond(in BluetoothDevice device, in int transport);
     boolean cancelBondProcess(in BluetoothDevice device);
     boolean removeBond(in BluetoothDevice device);
     int getBondState(in BluetoothDevice device);
diff --git a/core/java/android/bluetooth/IBluetoothGattCallback.aidl b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
index 18e3f54..f14cce0 100644
--- a/core/java/android/bluetooth/IBluetoothGattCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
@@ -16,6 +16,7 @@
 package android.bluetooth;
 
 import android.os.ParcelUuid;
+import android.bluetooth.le.AdvertiseSettings;
 import android.bluetooth.le.ScanResult;
 
 /**
@@ -26,7 +27,7 @@
     void onClientRegistered(in int status, in int clientIf);
     void onClientConnectionState(in int status, in int clientIf,
                                  in boolean connected, in String address);
-    void onScanResult(in String address, in int rssi, in byte[] advData);
+    void onScanResult(in ScanResult scanResult);
     void onBatchScanResults(in List<ScanResult> batchResults);
     void onGetService(in String address, in int srvcType, in int srvcInstId,
                       in ParcelUuid srvcUuid);
@@ -64,7 +65,8 @@
                              in int charInstId, in ParcelUuid charUuid,
                              in byte[] value);
     void onReadRemoteRssi(in String address, in int rssi, in int status);
-    void onMultiAdvertiseCallback(in int status);
+    void onMultiAdvertiseCallback(in int status, boolean isStart,
+                                  in AdvertiseSettings advertiseSettings);
     void onConfigureMTU(in String address, in int mtu, in int status);
     void onConnectionCongested(in String address, in boolean congested);
     void onFoundOrLost(in boolean onFound, in String address, in int rssi,
diff --git a/core/java/android/bluetooth/le/AdvertiseData.java b/core/java/android/bluetooth/le/AdvertiseData.java
index b137eeb..843cd84 100644
--- a/core/java/android/bluetooth/le/AdvertiseData.java
+++ b/core/java/android/bluetooth/le/AdvertiseData.java
@@ -17,14 +17,15 @@
 package android.bluetooth.le;
 
 import android.annotation.Nullable;
-import android.bluetooth.BluetoothUuid;
 import android.os.Parcel;
 import android.os.ParcelUuid;
 import android.os.Parcelable;
+import android.util.ArrayMap;
+import android.util.SparseArray;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
 /**
@@ -42,27 +43,18 @@
     @Nullable
     private final List<ParcelUuid> mServiceUuids;
 
-    private final int mManufacturerId;
-    @Nullable
-    private final byte[] mManufacturerSpecificData;
-
-    @Nullable
-    private final ParcelUuid mServiceDataUuid;
-    @Nullable
-    private final byte[] mServiceData;
-
+    private final SparseArray<byte[]> mManufacturerSpecificData;
+    private final Map<ParcelUuid, byte[]> mServiceData;
     private final boolean mIncludeTxPowerLevel;
     private final boolean mIncludeDeviceName;
 
     private AdvertiseData(List<ParcelUuid> serviceUuids,
-            ParcelUuid serviceDataUuid, byte[] serviceData,
-            int manufacturerId,
-            byte[] manufacturerSpecificData, boolean includeTxPowerLevel,
+            SparseArray<byte[]> manufacturerData,
+            Map<ParcelUuid, byte[]> serviceData,
+            boolean includeTxPowerLevel,
             boolean includeDeviceName) {
         mServiceUuids = serviceUuids;
-        mManufacturerId = manufacturerId;
-        mManufacturerSpecificData = manufacturerSpecificData;
-        mServiceDataUuid = serviceDataUuid;
+        mManufacturerSpecificData = manufacturerData;
         mServiceData = serviceData;
         mIncludeTxPowerLevel = includeTxPowerLevel;
         mIncludeDeviceName = includeDeviceName;
@@ -77,32 +69,17 @@
     }
 
     /**
-     * Returns the manufacturer identifier, which is a non-negative number assigned by Bluetooth
-     * SIG.
+     * Returns an array of manufacturer Id and the corresponding manufacturer specific data. The
+     * manufacturer id is a non-negative number assigned by Bluetooth SIG.
      */
-    public int getManufacturerId() {
-        return mManufacturerId;
-    }
-
-    /**
-     * Returns the manufacturer specific data which is the content of manufacturer specific data
-     * field. The first 2 bytes of the data contain the company id.
-     */
-    public byte[] getManufacturerSpecificData() {
+    public SparseArray<byte[]> getManufacturerSpecificData() {
         return mManufacturerSpecificData;
     }
 
     /**
-     * Returns a 16-bit UUID of the service that the service data is associated with.
+     * Returns a map of 16-bit UUID and its corresponding service data.
      */
-    public ParcelUuid getServiceDataUuid() {
-        return mServiceDataUuid;
-    }
-
-    /**
-     * Returns service data.
-     */
-    public byte[] getServiceData() {
+    public Map<ParcelUuid, byte[]> getServiceData() {
         return mServiceData;
     }
 
@@ -125,8 +102,8 @@
      */
     @Override
     public int hashCode() {
-        return Objects.hash(mServiceUuids, mManufacturerId, mManufacturerSpecificData,
-                mServiceDataUuid, mServiceData, mIncludeDeviceName, mIncludeTxPowerLevel);
+        return Objects.hash(mServiceUuids, mManufacturerSpecificData, mServiceData,
+                mIncludeDeviceName, mIncludeTxPowerLevel);
     }
 
     /**
@@ -142,20 +119,17 @@
         }
         AdvertiseData other = (AdvertiseData) obj;
         return Objects.equals(mServiceUuids, other.mServiceUuids) &&
-                mManufacturerId == other.mManufacturerId &&
-                Objects.deepEquals(mManufacturerSpecificData, other.mManufacturerSpecificData) &&
-                Objects.equals(mServiceDataUuid, other.mServiceDataUuid) &&
-                Objects.deepEquals(mServiceData, other.mServiceData) &&
+                Utils.equals(mManufacturerSpecificData, other.mManufacturerSpecificData) &&
+                Utils.equals(mServiceData, other.mServiceData) &&
                         mIncludeDeviceName == other.mIncludeDeviceName &&
                         mIncludeTxPowerLevel == other.mIncludeTxPowerLevel;
     }
 
     @Override
     public String toString() {
-        return "AdvertiseData [mServiceUuids=" + mServiceUuids + ", mManufacturerId="
-                + mManufacturerId + ", mManufacturerSpecificData="
-                + Arrays.toString(mManufacturerSpecificData) + ", mServiceDataUuid="
-                + mServiceDataUuid + ", mServiceData=" + Arrays.toString(mServiceData)
+        return "AdvertiseData [mServiceUuids=" + mServiceUuids + ", mManufacturerSpecificData="
+                + Utils.toString(mManufacturerSpecificData) + ", mServiceData="
+                + Utils.toString(mServiceData)
                 + ", mIncludeTxPowerLevel=" + mIncludeTxPowerLevel + ", mIncludeDeviceName="
                 + mIncludeDeviceName + "]";
     }
@@ -169,21 +143,30 @@
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeList(mServiceUuids);
 
-        dest.writeInt(mManufacturerId);
-        if (mManufacturerSpecificData == null) {
-            dest.writeInt(0);
-        } else {
-            dest.writeInt(1);
-            dest.writeInt(mManufacturerSpecificData.length);
-            dest.writeByteArray(mManufacturerSpecificData);
+        // mManufacturerSpecificData could not be null.
+        dest.writeInt(mManufacturerSpecificData.size());
+        for (int i = 0; i < mManufacturerSpecificData.size(); ++i) {
+            dest.writeInt(mManufacturerSpecificData.keyAt(i));
+            byte[] data = mManufacturerSpecificData.valueAt(i);
+            if (data == null) {
+                dest.writeInt(0);
+            } else {
+                dest.writeInt(1);
+                dest.writeInt(data.length);
+                dest.writeByteArray(data);
+            }
         }
-        dest.writeParcelable(mServiceDataUuid, flags);
-        if (mServiceData == null) {
-            dest.writeInt(0);
-        } else {
-            dest.writeInt(1);
-            dest.writeInt(mServiceData.length);
-            dest.writeByteArray(mServiceData);
+        dest.writeInt(mServiceData.size());
+        for (ParcelUuid uuid : mServiceData.keySet()) {
+            dest.writeParcelable(uuid, flags);
+            byte[] data = mServiceData.get(uuid);
+            if (data == null) {
+                dest.writeInt(0);
+            } else {
+                dest.writeInt(1);
+                dest.writeInt(data.length);
+                dest.writeByteArray(data);
+            }
         }
         dest.writeByte((byte) (getIncludeTxPowerLevel() ? 1 : 0));
         dest.writeByte((byte) (getIncludeDeviceName() ? 1 : 0));
@@ -209,20 +192,26 @@
                             builder.addServiceUuid(uuid);
                         }
                     }
-                    int manufacturerId = in.readInt();
-                    if (in.readInt() == 1) {
-                        int manufacturerDataLength = in.readInt();
-                        byte[] manufacturerData = new byte[manufacturerDataLength];
-                        in.readByteArray(manufacturerData);
-                        builder.setManufacturerData(manufacturerId, manufacturerData);
+                    int manufacturerSize = in.readInt();
+                    for (int i = 0; i < manufacturerSize; ++i) {
+                        int manufacturerId = in.readInt();
+                        if (in.readInt() == 1) {
+                            int manufacturerDataLength = in.readInt();
+                            byte[] manufacturerData = new byte[manufacturerDataLength];
+                            in.readByteArray(manufacturerData);
+                            builder.addManufacturerData(manufacturerId, manufacturerData);
+                        }
                     }
-                    ParcelUuid serviceDataUuid = in.readParcelable(
-                            ParcelUuid.class.getClassLoader());
-                    if (in.readInt() == 1) {
-                        int serviceDataLength = in.readInt();
-                        byte[] serviceData = new byte[serviceDataLength];
-                        in.readByteArray(serviceData);
-                        builder.setServiceData(serviceDataUuid, serviceData);
+                    int serviceDataSize = in.readInt();
+                    for (int i = 0; i < serviceDataSize; ++i) {
+                        ParcelUuid serviceDataUuid = in.readParcelable(
+                                ParcelUuid.class.getClassLoader());
+                        if (in.readInt() == 1) {
+                            int serviceDataLength = in.readInt();
+                            byte[] serviceData = new byte[serviceDataLength];
+                            in.readByteArray(serviceData);
+                            builder.addServiceData(serviceDataUuid, serviceData);
+                        }
                     }
                     builder.setIncludeTxPowerLevel(in.readByte() == 1);
                     builder.setIncludeDeviceName(in.readByte() == 1);
@@ -236,13 +225,8 @@
     public static final class Builder {
         @Nullable
         private List<ParcelUuid> mServiceUuids = new ArrayList<ParcelUuid>();
-        private int mManufacturerId = -1;
-        @Nullable
-        private byte[] mManufacturerSpecificData;
-        @Nullable
-        private ParcelUuid mServiceDataUuid;
-        @Nullable
-        private byte[] mServiceData;
+        private SparseArray<byte[]> mManufacturerSpecificData = new SparseArray<byte[]>();
+        private Map<ParcelUuid, byte[]> mServiceData = new ArrayMap<ParcelUuid, byte[]>();
         private boolean mIncludeTxPowerLevel;
         private boolean mIncludeDeviceName;
 
@@ -268,18 +252,17 @@
          * @throws IllegalArgumentException If the {@code serviceDataUuid} or {@code serviceData} is
          *             empty.
          */
-        public Builder setServiceData(ParcelUuid serviceDataUuid, byte[] serviceData) {
+        public Builder addServiceData(ParcelUuid serviceDataUuid, byte[] serviceData) {
             if (serviceDataUuid == null || serviceData == null) {
                 throw new IllegalArgumentException(
                         "serviceDataUuid or serviceDataUuid is null");
             }
-            mServiceDataUuid = serviceDataUuid;
-            mServiceData = serviceData;
+            mServiceData.put(serviceDataUuid, serviceData);
             return this;
         }
 
         /**
-         * Set manufacturer specific data.
+         * Add manufacturer specific data.
          * <p>
          * Please refer to the Bluetooth Assigned Numbers document provided by the <a
          * href="https://www.bluetooth.org">Bluetooth SIG</a> for a list of existing company
@@ -290,7 +273,7 @@
          * @throws IllegalArgumentException If the {@code manufacturerId} is negative or
          *             {@code manufacturerSpecificData} is null.
          */
-        public Builder setManufacturerData(int manufacturerId, byte[] manufacturerSpecificData) {
+        public Builder addManufacturerData(int manufacturerId, byte[] manufacturerSpecificData) {
             if (manufacturerId < 0) {
                 throw new IllegalArgumentException(
                         "invalid manufacturerId - " + manufacturerId);
@@ -298,8 +281,7 @@
             if (manufacturerSpecificData == null) {
                 throw new IllegalArgumentException("manufacturerSpecificData is null");
             }
-            mManufacturerId = manufacturerId;
-            mManufacturerSpecificData = manufacturerSpecificData;
+            mManufacturerSpecificData.put(manufacturerId, manufacturerSpecificData);
             return this;
         }
 
@@ -324,9 +306,7 @@
          * Build the {@link AdvertiseData}.
          */
         public AdvertiseData build() {
-            return new AdvertiseData(mServiceUuids,
-                    mServiceDataUuid,
-                    mServiceData, mManufacturerId, mManufacturerSpecificData,
+            return new AdvertiseData(mServiceUuids, mManufacturerSpecificData, mServiceData,
                     mIncludeTxPowerLevel, mIncludeDeviceName);
         }
     }
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index 4d128e7..331ebfc 100644
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -18,6 +18,7 @@
 
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCallbackWrapper;
 import android.bluetooth.BluetoothUuid;
 import android.bluetooth.IBluetoothGatt;
 import android.bluetooth.IBluetoothGattCallback;
@@ -209,13 +210,13 @@
                         num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT;
             }
         }
-        if (data.getServiceDataUuid() != null) {
+        for (ParcelUuid uuid : data.getServiceData().keySet()) {
             size += OVERHEAD_BYTES_PER_FIELD + SERVICE_DATA_UUID_LENGTH
-                    + byteLength(data.getServiceData());
+                    + byteLength(data.getServiceData().get(uuid));
         }
-        if (data.getManufacturerId() > 0) {
+        for (int i = 0; i < data.getManufacturerSpecificData().size(); ++i) {
             size += OVERHEAD_BYTES_PER_FIELD + MANUFACTURER_SPECIFIC_DATA_LENGTH +
-                    byteLength(data.getManufacturerSpecificData());
+                    byteLength(data.getManufacturerSpecificData().valueAt(i));
         }
         if (data.getIncludeTxPowerLevel()) {
             size += OVERHEAD_BYTES_PER_FIELD + 1; // tx power level value is one byte.
@@ -233,7 +234,7 @@
     /**
      * Bluetooth GATT interface callbacks for advertising.
      */
-    private static class AdvertiseCallbackWrapper extends IBluetoothGattCallback.Stub {
+    private static class AdvertiseCallbackWrapper extends BluetoothGattCallbackWrapper {
         private static final int LE_CALLBACK_TIMEOUT_MILLIS = 2000;
         private final AdvertiseCallback mAdvertiseCallback;
         private final AdvertiseData mAdvertisement;
@@ -245,7 +246,7 @@
         // -1: scan stopped
         // >0: registered and scan started
         private int mClientIf;
-        private boolean isAdvertising = false;
+        private boolean mIsAdvertising = false;
 
         public AdvertiseCallbackWrapper(AdvertiseCallback advertiseCallback,
                 AdvertiseData advertiseData, AdvertiseData scanResponse,
@@ -270,7 +271,7 @@
                 } catch (InterruptedException e) {
                     Log.e(TAG, "Callback reg wait interrupted: ", e);
                 }
-                started = (mClientIf > 0 && isAdvertising);
+                started = (mClientIf > 0 && mIsAdvertising);
             }
             return started;
         }
@@ -282,7 +283,7 @@
                 } catch (InterruptedException e) {
                     Log.e(TAG, "Callback reg wait interrupted: " + e);
                 }
-                return !isAdvertising;
+                return !mIsAdvertising;
             }
         }
 
@@ -312,155 +313,35 @@
         }
 
         @Override
-        public void onClientConnectionState(int status, int clientIf,
-                boolean connected, String address) {
-            // no op
-        }
-
-        @Override
-        public void onScanResult(String address, int rssi, byte[] advData) {
-            // no op
-        }
-
-        @Override
-        public void onGetService(String address, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid) {
-            // no op
-        }
-
-        @Override
-        public void onGetIncludedService(String address, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid,
-                int inclSrvcType, int inclSrvcInstId,
-                ParcelUuid inclSrvcUuid) {
-            // no op
-        }
-
-        @Override
-        public void onGetCharacteristic(String address, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid,
-                int charInstId, ParcelUuid charUuid,
-                int charProps) {
-            // no op
-        }
-
-        @Override
-        public void onGetDescriptor(String address, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid,
-                int charInstId, ParcelUuid charUuid,
-                int descInstId, ParcelUuid descUuid) {
-            // no op
-        }
-
-        @Override
-        public void onSearchComplete(String address, int status) {
-            // no op
-        }
-
-        @Override
-        public void onCharacteristicRead(String address, int status, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid,
-                int charInstId, ParcelUuid charUuid, byte[] value) {
-            // no op
-        }
-
-        @Override
-        public void onCharacteristicWrite(String address, int status, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid,
-                int charInstId, ParcelUuid charUuid) {
-            // no op
-        }
-
-        @Override
-        public void onNotify(String address, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid,
-                int charInstId, ParcelUuid charUuid,
-                byte[] value) {
-            // no op
-        }
-
-        @Override
-        public void onDescriptorRead(String address, int status, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid,
-                int charInstId, ParcelUuid charUuid,
-                int descInstId, ParcelUuid descrUuid, byte[] value) {
-            // no op
-        }
-
-        @Override
-        public void onDescriptorWrite(String address, int status, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid,
-                int charInstId, ParcelUuid charUuid,
-                int descInstId, ParcelUuid descrUuid) {
-            // no op
-        }
-
-        @Override
-        public void onExecuteWrite(String address, int status) {
-            // no op
-        }
-
-        @Override
-        public void onReadRemoteRssi(String address, int rssi, int status) {
-            // no op
-        }
-
-        @Override
-        public void onMultiAdvertiseCallback(int status) {
-            // TODO: This logic needs to be re-visited to account
-            // for whether the scan has actually been started
-            // or not. Toggling the isAdvertising does not seem
-            // correct.
+        public void onMultiAdvertiseCallback(int status, boolean isStart,
+                AdvertiseSettings settings) {
             synchronized (this) {
-                if (status == AdvertiseCallback.ADVERTISE_SUCCESS) {
-                    isAdvertising = !isAdvertising;
-                    if (!isAdvertising) {
-                        try {
-                            mBluetoothGatt.unregisterClient(mClientIf);
-                            mClientIf = -1;
-                        } catch (RemoteException e) {
-                            Log.e(TAG, "remote exception when unregistering", e);
-                        }
+                if (isStart) {
+                    if (status == AdvertiseCallback.ADVERTISE_SUCCESS) {
+                        // Start success
+                        mAdvertiseCallback.onStartSuccess(settings);
+                        mIsAdvertising = true;
                     } else {
-                        mAdvertiseCallback.onStartSuccess(null);
+                        // Start failure.
+                        mAdvertiseCallback.onStartFailure(status);
                     }
                 } else {
-                    if (!isAdvertising)
-                        mAdvertiseCallback.onStartFailure(status);
+                    // unregister client for stop.
+                    try {
+                        mBluetoothGatt.unregisterClient(mClientIf);
+                        mClientIf = -1;
+                        mIsAdvertising = false;
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "remote exception when unregistering", e);
+                    }
                 }
                 notifyAll();
             }
 
         }
-
-        /**
-         * Callback reporting LE ATT MTU.
-         *
-         * @hide
-         */
-        @Override
-        public void onConfigureMTU(String address, int mtu, int status) {
-            // no op
-        }
-
-        @Override
-        public void onConnectionCongested(String address, boolean congested) {
-            // no op
-        }
-
-        @Override
-        public void onBatchScanResults(List<ScanResult> results) {
-            // no op
-        }
-
-        @Override
-        public void onFoundOrLost(boolean onFound, String address, int rssi,
-                byte[] advData) {
-            // no op
-        }
     }
 
-    //TODO: move this api to a common util class.
+    // TODO: move this api to a common util class.
     private void checkAdapterState() {
         if (mBluetoothAdapter.getState() != mBluetoothAdapter.STATE_ON) {
             throw new IllegalStateException("BT Adapter is not turned ON");
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index f100ddc..45e466f 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -19,6 +19,7 @@
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCallbackWrapper;
 import android.bluetooth.IBluetoothGatt;
 import android.bluetooth.IBluetoothGattCallback;
 import android.bluetooth.IBluetoothManager;
@@ -186,7 +187,7 @@
     /**
      * Bluetooth GATT interface callbacks
      */
-    private static class BleScanCallbackWrapper extends IBluetoothGattCallback.Stub {
+    private static class BleScanCallbackWrapper extends BluetoothGattCallbackWrapper {
         private static final int REGISTRATION_CALLBACK_TIMEOUT_SECONDS = 5;
 
         private final ScanCallback mScanCallback;
@@ -284,37 +285,26 @@
             }
         }
 
-        @Override
-        public void onClientConnectionState(int status, int clientIf,
-                boolean connected, String address) {
-            // no op
-        }
-
         /**
          * Callback reporting an LE scan result.
          *
          * @hide
          */
         @Override
-        public void onScanResult(String address, int rssi, byte[] advData) {
+        public void onScanResult(final ScanResult scanResult) {
             if (DBG)
-                Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" + rssi);
+                Log.d(TAG, "onScanResult() - " + scanResult.toString());
 
             // Check null in case the scan has been stopped
             synchronized (this) {
                 if (mClientIf <= 0)
                     return;
             }
-            BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(
-                    address);
-            long scanNanos = SystemClock.elapsedRealtimeNanos();
-            final ScanResult result = new ScanResult(device, ScanRecord.parseFromBytes(advData),
-                    rssi, scanNanos);
             Handler handler = new Handler(Looper.getMainLooper());
             handler.post(new Runnable() {
                     @Override
                 public void run() {
-                    mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, result);
+                    mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, scanResult);
                 }
             });
 
@@ -332,104 +322,6 @@
         }
 
         @Override
-        public void onGetService(String address, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid) {
-            // no op
-        }
-
-        @Override
-        public void onGetIncludedService(String address, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid,
-                int inclSrvcType, int inclSrvcInstId,
-                ParcelUuid inclSrvcUuid) {
-            // no op
-        }
-
-        @Override
-        public void onGetCharacteristic(String address, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid,
-                int charInstId, ParcelUuid charUuid,
-                int charProps) {
-            // no op
-        }
-
-        @Override
-        public void onGetDescriptor(String address, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid,
-                int charInstId, ParcelUuid charUuid,
-                int descInstId, ParcelUuid descUuid) {
-            // no op
-        }
-
-        @Override
-        public void onSearchComplete(String address, int status) {
-            // no op
-        }
-
-        @Override
-        public void onCharacteristicRead(String address, int status, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid,
-                int charInstId, ParcelUuid charUuid, byte[] value) {
-            // no op
-        }
-
-        @Override
-        public void onCharacteristicWrite(String address, int status, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid,
-                int charInstId, ParcelUuid charUuid) {
-            // no op
-        }
-
-        @Override
-        public void onNotify(String address, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid,
-                int charInstId, ParcelUuid charUuid,
-                byte[] value) {
-            // no op
-        }
-
-        @Override
-        public void onDescriptorRead(String address, int status, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid,
-                int charInstId, ParcelUuid charUuid,
-                int descInstId, ParcelUuid descrUuid, byte[] value) {
-            // no op
-        }
-
-        @Override
-        public void onDescriptorWrite(String address, int status, int srvcType,
-                int srvcInstId, ParcelUuid srvcUuid,
-                int charInstId, ParcelUuid charUuid,
-                int descInstId, ParcelUuid descrUuid) {
-            // no op
-        }
-
-        @Override
-        public void onExecuteWrite(String address, int status) {
-            // no op
-        }
-
-        @Override
-        public void onReadRemoteRssi(String address, int rssi, int status) {
-            // no op
-        }
-
-        @Override
-        public void onMultiAdvertiseCallback(int status) {
-            // no op
-        }
-
-        @Override
-        public void onConfigureMTU(String address, int mtu, int status) {
-            // no op
-        }
-
-        @Override
-        public void onConnectionCongested(String address, boolean congested) {
-            // no op
-        }
-
-        @Override
         public void onFoundOrLost(boolean onFound, String address, int rssi,
                 byte[] advData) {
             if (DBG) {
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index 30aaf2e..d1b93d2 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -181,7 +181,7 @@
                                 byte[] serviceDataMask = new byte[serviceDataMaskLength];
                                 in.readByteArray(serviceDataMask);
                                 builder.setServiceData(
-                                            servcieDataUuid, serviceData, serviceDataMask);
+                                        servcieDataUuid, serviceData, serviceDataMask);
                             }
                         }
                     }
@@ -242,9 +242,6 @@
         return mServiceDataMask;
     }
 
-    /**
-     * @hide
-     */
     @Nullable
     public ParcelUuid getServiceDataUuid() {
         return mServiceDataUuid;
@@ -303,19 +300,17 @@
         }
 
         // Service data match
-        if (mServiceData != null) {
-            if (!Objects.equals(mServiceDataUuid, scanRecord.getServiceDataUuid()) ||
-                    !matchesPartialData(mServiceData, mServiceDataMask,
-                            scanRecord.getServiceData())) {
+        if (mServiceDataUuid != null) {
+            if (!matchesPartialData(mServiceData, mServiceDataMask,
+                    scanRecord.getServiceData(mServiceDataUuid))) {
                 return false;
             }
         }
 
         // Manufacturer data match.
-        if (mManufacturerData != null) {
-            if (mManufacturerId != scanRecord.getManufacturerId() ||
-                    !matchesPartialData(mManufacturerData,
-                            mManufacturerDataMask, scanRecord.getManufacturerSpecificData())) {
+        if (mManufacturerId >= 0) {
+            if (!matchesPartialData(mManufacturerData, mManufacturerDataMask,
+                    scanRecord.getManufacturerSpecificData(mManufacturerId))) {
                 return false;
             }
         }
diff --git a/core/java/android/bluetooth/le/ScanRecord.java b/core/java/android/bluetooth/le/ScanRecord.java
index e564c7d..e7f33ff1 100644
--- a/core/java/android/bluetooth/le/ScanRecord.java
+++ b/core/java/android/bluetooth/le/ScanRecord.java
@@ -19,11 +19,14 @@
 import android.annotation.Nullable;
 import android.bluetooth.BluetoothUuid;
 import android.os.ParcelUuid;
+import android.util.ArrayMap;
 import android.util.Log;
+import android.util.SparseArray;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Represents a scan record from Bluetooth LE scan.
@@ -53,14 +56,9 @@
     @Nullable
     private final List<ParcelUuid> mServiceUuids;
 
-    private final int mManufacturerId;
-    @Nullable
-    private final byte[] mManufacturerSpecificData;
+    private final SparseArray<byte[]> mManufacturerSpecificData;
 
-    @Nullable
-    private final ParcelUuid mServiceDataUuid;
-    @Nullable
-    private final byte[] mServiceData;
+    private final Map<ParcelUuid, byte[]> mServiceData;
 
     // Transmission power level(in dB).
     private final int mTxPowerLevel;
@@ -81,43 +79,49 @@
 
     /**
      * Returns a list of service UUIDs within the advertisement that are used to identify the
-     * bluetooth gatt services.
+     * bluetooth GATT services.
      */
     public List<ParcelUuid> getServiceUuids() {
         return mServiceUuids;
     }
 
     /**
-     * Returns the manufacturer identifier, which is a non-negative number assigned by Bluetooth
-     * SIG.
+     * Returns a sparse array of manufacturer identifier and its corresponding manufacturer specific
+     * data.
      */
-    public int getManufacturerId() {
-        return mManufacturerId;
-    }
-
-    /**
-     * Returns the manufacturer specific data which is the content of manufacturer specific data
-     * field.
-     */
-    public byte[] getManufacturerSpecificData() {
+    public SparseArray<byte[]> getManufacturerSpecificData() {
         return mManufacturerSpecificData;
     }
 
     /**
-     * Returns a 16-bit UUID of the service that the service data is associated with.
+     * Returns the manufacturer specific data associated with the manufacturer id. Returns
+     * {@code null} if the {@code manufacturerId} is not found.
      */
-    public ParcelUuid getServiceDataUuid() {
-        return mServiceDataUuid;
+    @Nullable
+    public byte[] getManufacturerSpecificData(int manufacturerId) {
+        return mManufacturerSpecificData.get(manufacturerId);
     }
 
     /**
-     * Returns service data.
+     * Returns a map of service UUID and its corresponding service data.
      */
-    public byte[] getServiceData() {
+    public Map<ParcelUuid, byte[]> getServiceData() {
         return mServiceData;
     }
 
     /**
+     * Returns the service data byte array associated with the {@code serviceUuid}. Returns
+     * {@code null} if the {@code serviceDataUuid} is not found.
+     */
+    @Nullable
+    public byte[] getServiceData(ParcelUuid serviceDataUuid) {
+        if (serviceDataUuid == null) {
+            return null;
+        }
+        return mServiceData.get(serviceDataUuid);
+    }
+
+    /**
      * Returns the transmission power level of the packet in dBm. Returns {@link Integer#MIN_VALUE}
      * if the field is not set. This value can be used to calculate the path loss of a received
      * packet using the following equation:
@@ -144,14 +148,12 @@
     }
 
     private ScanRecord(List<ParcelUuid> serviceUuids,
-            ParcelUuid serviceDataUuid, byte[] serviceData,
-            int manufacturerId,
-            byte[] manufacturerSpecificData, int advertiseFlags, int txPowerLevel,
+            SparseArray<byte[]> manufacturerData,
+            Map<ParcelUuid, byte[]> serviceData,
+            int advertiseFlags, int txPowerLevel,
             String localName, byte[] bytes) {
         mServiceUuids = serviceUuids;
-        mManufacturerId = manufacturerId;
-        mManufacturerSpecificData = manufacturerSpecificData;
-        mServiceDataUuid = serviceDataUuid;
+        mManufacturerSpecificData = manufacturerData;
         mServiceData = serviceData;
         mDeviceName = localName;
         mAdvertiseFlags = advertiseFlags;
@@ -168,7 +170,6 @@
      * order.
      *
      * @param scanRecord The scan record of Bluetooth LE advertisement and/or scan response.
-     *
      * @hide
      */
     public static ScanRecord parseFromBytes(byte[] scanRecord) {
@@ -181,10 +182,9 @@
         List<ParcelUuid> serviceUuids = new ArrayList<ParcelUuid>();
         String localName = null;
         int txPowerLevel = Integer.MIN_VALUE;
-        ParcelUuid serviceDataUuid = null;
-        byte[] serviceData = null;
-        int manufacturerId = -1;
-        byte[] manufacturerSpecificData = null;
+
+        SparseArray<byte[]> manufacturerData = new SparseArray<byte[]>();
+        Map<ParcelUuid, byte[]> serviceData = new ArrayMap<ParcelUuid, byte[]>();
 
         try {
             while (currentPos < scanRecord.length) {
@@ -230,16 +230,20 @@
                         int serviceUuidLength = BluetoothUuid.UUID_BYTES_16_BIT;
                         byte[] serviceDataUuidBytes = extractBytes(scanRecord, currentPos,
                                 serviceUuidLength);
-                        serviceDataUuid = BluetoothUuid.parseUuidFrom(serviceDataUuidBytes);
-                        serviceData = extractBytes(scanRecord, currentPos + 2, dataLength - 2);
+                        ParcelUuid serviceDataUuid = BluetoothUuid.parseUuidFrom(
+                                serviceDataUuidBytes);
+                        byte[] serviceDataArray = extractBytes(scanRecord,
+                                currentPos + serviceUuidLength, dataLength - serviceUuidLength);
+                        serviceData.put(serviceDataUuid, serviceDataArray);
                         break;
                     case DATA_TYPE_MANUFACTURER_SPECIFIC_DATA:
                         // The first two bytes of the manufacturer specific data are
                         // manufacturer ids in little endian.
-                        manufacturerId = ((scanRecord[currentPos + 1] & 0xFF) << 8) +
+                        int manufacturerId = ((scanRecord[currentPos + 1] & 0xFF) << 8) +
                                 (scanRecord[currentPos] & 0xFF);
-                        manufacturerSpecificData = extractBytes(scanRecord, currentPos + 2,
+                        byte[] manufacturerDataBytes = extractBytes(scanRecord, currentPos + 2,
                                 dataLength - 2);
+                        manufacturerData.put(manufacturerId, manufacturerDataBytes);
                         break;
                     default:
                         // Just ignore, we don't handle such data type.
@@ -251,9 +255,8 @@
             if (serviceUuids.isEmpty()) {
                 serviceUuids = null;
             }
-            return new ScanRecord(serviceUuids, serviceDataUuid, serviceData,
-                    manufacturerId, manufacturerSpecificData, advertiseFlag, txPowerLevel,
-                    localName, scanRecord);
+            return new ScanRecord(serviceUuids, manufacturerData, serviceData,
+                    advertiseFlag, txPowerLevel, localName, scanRecord);
         } catch (IndexOutOfBoundsException e) {
             Log.e(TAG, "unable to parse scan record: " + Arrays.toString(scanRecord));
             return null;
@@ -263,13 +266,11 @@
     @Override
     public String toString() {
         return "ScanRecord [mAdvertiseFlags=" + mAdvertiseFlags + ", mServiceUuids=" + mServiceUuids
-                + ", mManufacturerId=" + mManufacturerId + ", mManufacturerSpecificData="
-                + Arrays.toString(mManufacturerSpecificData) + ", mServiceDataUuid="
-                + mServiceDataUuid + ", mServiceData=" + Arrays.toString(mServiceData)
+                + ", mManufacturerSpecificData=" + Utils.toString(mManufacturerSpecificData)
+                + ", mServiceData=" + Utils.toString(mServiceData)
                 + ", mTxPowerLevel=" + mTxPowerLevel + ", mDeviceName=" + mDeviceName + "]";
     }
 
-
     // Parse service UUIDs.
     private static int parseServiceUuid(byte[] scanRecord, int currentPos, int dataLength,
             int uuidLength, List<ParcelUuid> serviceUuids) {
diff --git a/core/java/android/bluetooth/le/Utils.java b/core/java/android/bluetooth/le/Utils.java
new file mode 100644
index 0000000..8598dd7
--- /dev/null
+++ b/core/java/android/bluetooth/le/Utils.java
@@ -0,0 +1,126 @@
+/*
+ * 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.bluetooth.le;
+
+import android.util.SparseArray;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Helper class for Bluetooth LE utils.
+ *
+ * @hide
+ */
+public class Utils {
+
+    /**
+     * Returns a string composed from a {@link SparseArray}.
+     */
+    static String toString(SparseArray<byte[]> array) {
+        if (array == null) {
+            return "null";
+        }
+        if (array.size() == 0) {
+            return "{}";
+        }
+        StringBuilder buffer = new StringBuilder();
+        buffer.append('{');
+        for (int i = 0; i < array.size(); ++i) {
+            buffer.append(array.keyAt(i)).append("=").append(array.valueAt(i));
+        }
+        buffer.append('}');
+        return buffer.toString();
+    }
+
+    /**
+     * Returns a string composed from a {@link Map}.
+     */
+    static <T> String toString(Map<T, byte[]> map) {
+        if (map == null) {
+            return "null";
+        }
+        if (map.isEmpty()) {
+            return "{}";
+        }
+        StringBuilder buffer = new StringBuilder();
+        buffer.append('{');
+        Iterator<Map.Entry<T, byte[]>> it = map.entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry<T, byte[]> entry = it.next();
+            Object key = entry.getKey();
+            buffer.append(key).append("=").append(Arrays.toString(map.get(key)));
+            if (it.hasNext()) {
+                buffer.append(", ");
+            }
+        }
+        buffer.append('}');
+        return buffer.toString();
+    }
+
+    /**
+     * Check whether two {@link SparseArray} equal.
+     */
+    static boolean equals(SparseArray<byte[]> array, SparseArray<byte[]> otherArray) {
+        if (array == otherArray) {
+            return true;
+        }
+        if (array == null || otherArray == null) {
+            return false;
+        }
+        if (array.size() != otherArray.size()) {
+            return false;
+        }
+
+        // Keys are guaranteed in ascending order when indices are in ascending order.
+        for (int i = 0; i < array.size(); ++i) {
+            if (array.keyAt(i) != otherArray.keyAt(i) ||
+                    !Arrays.equals(array.valueAt(i), otherArray.valueAt(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Check whether two {@link Map} equal.
+     */
+    static <T> boolean equals(Map<T, byte[]> map, Map<T, byte[]> otherMap) {
+        if (map == otherMap) {
+            return true;
+        }
+        if (map == null || otherMap == null) {
+            return false;
+        }
+        if (map.size() != otherMap.size()) {
+            return false;
+        }
+        Set<T> keys = map.keySet();
+        if (!keys.equals(otherMap.keySet())) {
+            return false;
+        }
+        for (T key : keys) {
+            if (!Objects.deepEquals(map.get(key), otherMap.get(key))) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index be9782f..5f6fb6e 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -17,6 +17,7 @@
 package android.content;
 
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 
 import android.app.AppOpsManager;
 import android.content.pm.PathPermission;
@@ -192,11 +193,12 @@
         public Cursor query(String callingPkg, Uri uri, String[] projection,
                 String selection, String[] selectionArgs, String sortOrder,
                 ICancellationSignal cancellationSignal) {
+            getAndEnforceUserId(uri);
+            uri = getUriWithoutUserId(uri);
             if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                 return rejectQuery(uri, projection, selection, selectionArgs, sortOrder,
                         CancellationSignal.fromTransport(cancellationSignal));
             }
-            uri = getUriWithoutUserId(uri);
             final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.query(
@@ -209,17 +211,18 @@
 
         @Override
         public String getType(Uri uri) {
+            getAndEnforceUserId(uri);
             uri = getUriWithoutUserId(uri);
             return ContentProvider.this.getType(uri);
         }
 
         @Override
         public Uri insert(String callingPkg, Uri uri, ContentValues initialValues) {
+            int userId = getAndEnforceUserId(uri);
+            uri = getUriWithoutUserId(uri);
             if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                 return rejectInsert(uri, initialValues);
             }
-            int userId = getUserIdFromUri(uri);
-            uri = getUriWithoutUserId(uri);
             final String original = setCallingPackage(callingPkg);
             try {
                 return maybeAddUserId(ContentProvider.this.insert(uri, initialValues), userId);
@@ -230,10 +233,11 @@
 
         @Override
         public int bulkInsert(String callingPkg, Uri uri, ContentValues[] initialValues) {
+            getAndEnforceUserId(uri);
+            uri = getUriWithoutUserId(uri);
             if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
             }
-            uri = getUriWithoutUserId(uri);
             final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.bulkInsert(uri, initialValues);
@@ -250,7 +254,12 @@
             final int[] userIds = new int[numOperations];
             for (int i = 0; i < numOperations; i++) {
                 ContentProviderOperation operation = operations.get(i);
-                userIds[i] = getUserIdFromUri(operation.getUri());
+                userIds[i] = getAndEnforceUserId(operation.getUri());
+                if (userIds[i] != UserHandle.USER_CURRENT) {
+                    // Removing the user id from the uri.
+                    operation = new ContentProviderOperation(operation, true);
+                    operations.set(i, operation);
+                }
                 if (operation.isReadOperation()) {
                     if (enforceReadPermission(callingPkg, operation.getUri())
                             != AppOpsManager.MODE_ALLOWED) {
@@ -263,11 +272,6 @@
                         throw new OperationApplicationException("App op not allowed", 0);
                     }
                 }
-                if (userIds[i] != UserHandle.USER_CURRENT) {
-                    // Removing the user id from the uri.
-                    operation = new ContentProviderOperation(operation, true);
-                }
-                operations.set(i, operation);
             }
             final String original = setCallingPackage(callingPkg);
             try {
@@ -286,10 +290,11 @@
 
         @Override
         public int delete(String callingPkg, Uri uri, String selection, String[] selectionArgs) {
+            getAndEnforceUserId(uri);
+            uri = getUriWithoutUserId(uri);
             if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
             }
-            uri = getUriWithoutUserId(uri);
             final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.delete(uri, selection, selectionArgs);
@@ -301,10 +306,11 @@
         @Override
         public int update(String callingPkg, Uri uri, ContentValues values, String selection,
                 String[] selectionArgs) {
+            getAndEnforceUserId(uri);
+            uri = getUriWithoutUserId(uri);
             if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
             }
-            uri = getUriWithoutUserId(uri);
             final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.update(uri, values, selection, selectionArgs);
@@ -317,8 +323,9 @@
         public ParcelFileDescriptor openFile(
                 String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal)
                 throws FileNotFoundException {
-            enforceFilePermission(callingPkg, uri, mode);
+            getAndEnforceUserId(uri);
             uri = getUriWithoutUserId(uri);
+            enforceFilePermission(callingPkg, uri, mode);
             final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.openFile(
@@ -332,8 +339,9 @@
         public AssetFileDescriptor openAssetFile(
                 String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal)
                 throws FileNotFoundException {
-            enforceFilePermission(callingPkg, uri, mode);
+            getAndEnforceUserId(uri);
             uri = getUriWithoutUserId(uri);
+            enforceFilePermission(callingPkg, uri, mode);
             final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.openAssetFile(
@@ -355,6 +363,7 @@
 
         @Override
         public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
+            getAndEnforceUserId(uri);
             uri = getUriWithoutUserId(uri);
             return ContentProvider.this.getStreamTypes(uri, mimeTypeFilter);
         }
@@ -362,8 +371,9 @@
         @Override
         public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri uri, String mimeType,
                 Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException {
-            enforceFilePermission(callingPkg, uri, "r");
+            getAndEnforceUserId(uri);
             uri = getUriWithoutUserId(uri);
+            enforceFilePermission(callingPkg, uri, "r");
             final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.openTypedAssetFile(
@@ -380,11 +390,11 @@
 
         @Override
         public Uri canonicalize(String callingPkg, Uri uri) {
+            int userId = getAndEnforceUserId(uri);
+            uri = getUriWithoutUserId(uri);
             if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                 return null;
             }
-            int userId = getUserIdFromUri(uri);
-            uri = getUriWithoutUserId(uri);
             final String original = setCallingPackage(callingPkg);
             try {
                 return maybeAddUserId(ContentProvider.this.canonicalize(uri), userId);
@@ -395,11 +405,11 @@
 
         @Override
         public Uri uncanonicalize(String callingPkg, Uri uri) {
+            int userId = getAndEnforceUserId(uri);
+            uri = getUriWithoutUserId(uri);
             if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                 return null;
             }
-            int userId = getUserIdFromUri(uri);
-            uri = getUriWithoutUserId(uri);
             final String original = setCallingPackage(callingPkg);
             try {
                 return maybeAddUserId(ContentProvider.this.uncanonicalize(uri), userId);
@@ -438,6 +448,12 @@
         }
     }
 
+    boolean checkUser(int pid, int uid, Context context) {
+        return UserHandle.getUserId(uid) == context.getUserId()
+                || context.checkPermission(INTERACT_ACROSS_USERS, pid, uid)
+                == PERMISSION_GRANTED;
+    }
+
     /** {@hide} */
     protected void enforceReadPermissionInner(Uri uri) throws SecurityException {
         final Context context = getContext();
@@ -449,7 +465,7 @@
             return;
         }
 
-        if (mExported) {
+        if (mExported && checkUser(pid, uid, context)) {
             final String componentPerm = getReadPermission();
             if (componentPerm != null) {
                 if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) {
@@ -511,7 +527,7 @@
             return;
         }
 
-        if (mExported) {
+        if (mExported && checkUser(pid, uid, context)) {
             final String componentPerm = getWritePermission();
             if (componentPerm != null) {
                 if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) {
@@ -1711,11 +1727,20 @@
     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         writer.println("nothing to dump");
     }
+    /** @hide */
+    private int getAndEnforceUserId(Uri uri) {
+        int userId = getUserIdFromUri(uri, UserHandle.USER_CURRENT);
+        if (userId != UserHandle.USER_CURRENT && userId != mContext.getUserId()) {
+            throw new SecurityException("trying to query a ContentProvider in user "
+                    + mContext.getUserId() + "with a uri belonging to user " + userId);
+        }
+        return userId;
+    }
 
     /** @hide */
     public static int getUserIdFromAuthority(String auth, int defaultUserId) {
         if (auth == null) return defaultUserId;
-        int end = auth.indexOf('@');
+        int end = auth.lastIndexOf('@');
         if (end == -1) return defaultUserId;
         String userIdString = auth.substring(0, end);
         try {
@@ -1750,7 +1775,7 @@
      */
     public static String getAuthorityWithoutUserId(String auth) {
         if (auth == null) return null;
-        int end = auth.indexOf('@');
+        int end = auth.lastIndexOf('@');
         return auth.substring(end+1);
     }
 
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index f3a7b1c..7417208 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2076,7 +2076,7 @@
             CLIPBOARD_SERVICE,
             INPUT_METHOD_SERVICE,
             TEXT_SERVICES_MANAGER_SERVICE,
-            //@hide: APPWIDGET_SERVICE,
+            APPWIDGET_SERVICE,
             //@hide: BACKUP_SERVICE,
             DROPBOX_SERVICE,
             DEVICE_POLICY_SERVICE,
@@ -2596,7 +2596,6 @@
      * Use with {@link #getSystemService} to retrieve a
      * {@link android.appwidget.AppWidgetManager} for accessing AppWidgets.
      *
-     * @hide
      * @see #getSystemService
      */
     public static final String APPWIDGET_SERVICE = "appwidget";
@@ -3306,6 +3305,14 @@
             throws PackageManager.NameNotFoundException;
 
     /**
+     * Creates a context given an {@link android.content.pm.ApplicationInfo}.
+     *
+     * @hide
+     */
+    public abstract Context createApplicationContext(ApplicationInfo application,
+            int flags) throws PackageManager.NameNotFoundException;
+
+    /**
      * Get the userId associated with this context
      * @return user id
      *
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 4e1c4a7..ad7c350 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -666,6 +666,12 @@
     }
 
     /** @hide */
+    public Context createApplicationContext(ApplicationInfo application,
+            int flags) throws PackageManager.NameNotFoundException {
+        return mBase.createApplicationContext(application, flags);
+    }
+
+    /** @hide */
     @Override
     public int getUserId() {
         return mBase.getUserId();
diff --git a/core/java/android/hardware/hdmi/HdmiCecDeviceInfo.aidl b/core/java/android/content/pm/IPackageDeleteObserver2.aidl
similarity index 71%
copy from core/java/android/hardware/hdmi/HdmiCecDeviceInfo.aidl
copy to core/java/android/content/pm/IPackageDeleteObserver2.aidl
index 1615910..bff3baa 100644
--- a/core/java/android/hardware/hdmi/HdmiCecDeviceInfo.aidl
+++ b/core/java/android/content/pm/IPackageDeleteObserver2.aidl
@@ -14,6 +14,12 @@
  * limitations under the License.
  */
 
-package android.hardware.hdmi;
+package android.content.pm;
 
-parcelable HdmiCecDeviceInfo;
+import android.content.Intent;
+
+/** {@hide} */
+oneway interface IPackageDeleteObserver2 {
+    void onUserActionRequired(in Intent intent);
+    void onPackageDeleted(String packageName, int returnCode, String msg);
+}
diff --git a/core/java/android/content/pm/IPackageInstallObserver2.aidl b/core/java/android/content/pm/IPackageInstallObserver2.aidl
index 824d730..bb5f22a 100644
--- a/core/java/android/content/pm/IPackageInstallObserver2.aidl
+++ b/core/java/android/content/pm/IPackageInstallObserver2.aidl
@@ -16,7 +16,7 @@
 
 package android.content.pm;
 
-import android.content.IntentSender;
+import android.content.Intent;
 import android.os.Bundle;
 
 /**
@@ -25,6 +25,8 @@
  * @hide
  */
 oneway interface IPackageInstallObserver2 {
+    void onUserActionRequired(in Intent intent);
+
     /**
      * The install operation has completed.  {@code returnCode} holds a numeric code
      * indicating success or failure.  In certain cases the {@code extras} Bundle will
@@ -40,5 +42,5 @@
      * </tr>
      * </table>
      */
-    void packageInstalled(String basePackageName, in Bundle extras, int returnCode, String msg);
+    void onPackageInstalled(String basePackageName, int returnCode, String msg, in Bundle extras);
 }
diff --git a/core/java/android/content/pm/IPackageInstaller.aidl b/core/java/android/content/pm/IPackageInstaller.aidl
index 0c65034..176a81c 100644
--- a/core/java/android/content/pm/IPackageInstaller.aidl
+++ b/core/java/android/content/pm/IPackageInstaller.aidl
@@ -16,7 +16,7 @@
 
 package android.content.pm;
 
-import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageDeleteObserver2;
 import android.content.pm.IPackageInstallerCallback;
 import android.content.pm.IPackageInstallerSession;
 import android.content.pm.InstallSessionInfo;
@@ -35,6 +35,6 @@
     void registerCallback(IPackageInstallerCallback callback, int userId);
     void unregisterCallback(IPackageInstallerCallback callback);
 
-    void uninstall(String packageName, int flags, in IPackageDeleteObserver observer, int userId);
-    void uninstallSplit(String packageName, String splitName, int flags, in IPackageDeleteObserver observer, int userId);
+    void uninstall(String packageName, int flags, in IPackageDeleteObserver2 observer, int userId);
+    void uninstallSplit(String packageName, String splitName, int flags, in IPackageDeleteObserver2 observer, int userId);
 }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 7196372..44478d4 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -24,10 +24,10 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ContainerEncryptionParams;
 import android.content.pm.FeatureInfo;
-import android.content.pm.IPackageInstallObserver;
 import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.IPackageInstaller;
 import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageDeleteObserver2;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageMoveObserver;
 import android.content.pm.IPackageStatsObserver;
@@ -202,6 +202,10 @@
 
     void setInstallerPackageName(in String targetPackage, in String installerPackageName);
 
+    /** @deprecated rawr, don't call AIDL methods directly! */
+    void deletePackageAsUser(in String packageName, IPackageDeleteObserver observer,
+            int userId, int flags);
+
     /**
      * Delete a package for a specific user.
      *
@@ -210,8 +214,7 @@
      * @param userId the id of the user for whom to delete the package
      * @param flags - possible values: {@link #DONT_DELETE_DATA}
      */
-    void deletePackageAsUser(in String packageName, IPackageDeleteObserver observer,
-            int userId, int flags);
+    void deletePackage(in String packageName, IPackageDeleteObserver2 observer, int userId, int flags);
 
     String getInstallerPackageName(in String packageName);
 
@@ -233,7 +236,7 @@
             in ComponentName[] set, in ComponentName activity, int userId);
 
     void replacePreferredActivity(in IntentFilter filter, int match,
-            in ComponentName[] set, in ComponentName activity);
+            in ComponentName[] set, in ComponentName activity, int userId);
 
     void clearPackagePreferredActivities(String packageName);
 
@@ -250,6 +253,9 @@
     void addCrossProfileIntentsForPackage(in String packageName, int sourceUserId,
             int targetUserId);
 
+    void removeCrossProfileIntentsForPackage(String packageName, int sourceUserId,
+            int targetUserId);
+
     void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage, int ownerUserId);
 
     /**
diff --git a/core/java/android/content/pm/LauncherActivityInfo.java b/core/java/android/content/pm/LauncherActivityInfo.java
index 5d48868..0cff08b 100644
--- a/core/java/android/content/pm/LauncherActivityInfo.java
+++ b/core/java/android/content/pm/LauncherActivityInfo.java
@@ -179,8 +179,7 @@
         }
 
         if (originalIcon instanceof BitmapDrawable) {
-            return mUm.getBadgedDrawableForUser(
-                    originalIcon, mUser);
+            return mUm.getBadgedIconForUser(originalIcon, mUser);
         } else {
             Log.e(TAG, "Unable to create badged icon for " + mActivityInfo);
         }
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 8af827e..01c080d 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -20,8 +20,9 @@
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.app.PackageDeleteObserver;
 import android.app.PackageInstallObserver;
-import android.app.PackageUninstallObserver;
+import android.content.Intent;
 import android.os.Bundle;
 import android.os.FileBridge;
 import android.os.Handler;
@@ -114,6 +115,9 @@
      *
      * @throws IOException if parameters were unsatisfiable, such as lack of
      *             disk space or unavailable media.
+     * @return positive, non-zero unique ID that represents the created session.
+     *         This ID remains consistent across device reboots until the
+     *         session is finalized. IDs are not reused during a given boot.
      */
     public int createSession(@NonNull InstallSessionParams params) throws IOException {
         try {
@@ -533,15 +537,25 @@
     }
 
     /**
-     * Final result of an uninstall request.
+     * Events for a specific uninstall request.
      */
     public static abstract class UninstallCallback {
+        /**
+         * User action is required to proceed. You can start the given intent
+         * activity to involve the user and continue.
+         * <p>
+         * You may choose to immediately launch the intent if the user is
+         * actively using your app. However, you should use a notification to
+         * guide the user back into your app if not currently active.
+         */
+        public abstract void onUserActionRequired(Intent intent);
+
         public abstract void onSuccess();
         public abstract void onFailure(String msg);
     }
 
     /** {@hide} */
-    private static class UninstallCallbackDelegate extends PackageUninstallObserver {
+    private static class UninstallCallbackDelegate extends PackageDeleteObserver {
         private final UninstallCallback target;
 
         public UninstallCallbackDelegate(UninstallCallback target) {
@@ -549,11 +563,16 @@
         }
 
         @Override
-        public void onUninstallFinished(String basePackageName, int returnCode) {
+        public void onUserActionRequired(Intent intent) {
+            target.onUserActionRequired(intent);
+        }
+
+        @Override
+        public void onPackageDeleted(String basePackageName, int returnCode, String msg) {
             if (returnCode == PackageManager.DELETE_SUCCEEDED) {
                 target.onSuccess();
             } else {
-                final String msg = PackageManager.deleteStatusToString(returnCode);
+                msg = PackageManager.deleteStatusToString(returnCode) + ": " + msg;
                 target.onFailure(msg);
             }
         }
@@ -609,6 +628,16 @@
 
         public static final String EXTRA_PACKAGE_NAME = "android.content.pm.extra.PACKAGE_NAME";
 
+        /**
+         * User action is required to proceed. You can start the given intent
+         * activity to involve the user and continue.
+         * <p>
+         * You may choose to immediately launch the intent if the user is
+         * actively using your app. However, you should use a notification to
+         * guide the user back into your app if not currently active.
+         */
+        public abstract void onUserActionRequired(Intent intent);
+
         public abstract void onSuccess();
         public abstract void onFailure(int failureReason, String msg, Bundle extras);
     }
@@ -622,8 +651,13 @@
         }
 
         @Override
-        public void packageInstalled(String basePackageName, Bundle extras, int returnCode,
-                String msg) {
+        public void onUserActionRequired(Intent intent) {
+            target.onUserActionRequired(intent);
+        }
+
+        @Override
+        public void onPackageInstalled(String basePackageName, int returnCode, String msg,
+                Bundle extras) {
             if (returnCode == PackageManager.INSTALL_SUCCEEDED) {
                 target.onSuccess();
             } else {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index c5dcd8e..1e4ed31 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3523,6 +3523,15 @@
             ComponentName[] set, ComponentName activity);
 
     /**
+     * @hide
+     */
+    @Deprecated
+    public void replacePreferredActivityAsUser(IntentFilter filter, int match,
+           ComponentName[] set, ComponentName activity, int userId) {
+        throw new RuntimeException("Not implemented. Must override in a subclass.");
+    }
+
+    /**
      * Remove all preferred activity mappings, previously added with
      * {@link #addPreferredActivity}, from the
      * system whose activities are implemented in the given package name.
@@ -3761,6 +3770,15 @@
      */
     public abstract void addCrossProfileIntentsForPackage(String packageName,
             int sourceUserId, int targetUserId);
+
+    /**
+     * Removes all intents for {@link packageName} for user {@link sourceUserId} to user
+     * {@link targetUserId}.
+     * @hide
+     */
+    public abstract void removeCrossProfileIntentsForPackage(String packageName,
+            int sourceUserId, int targetUserId);
+
     /**
      * @hide
      */
diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
index 986f9a8..711edf4 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
@@ -94,7 +94,7 @@
     static final boolean LIE_ABOUT_AF = false;
     static final boolean LIE_ABOUT_AF_MAX_REGIONS = false;
     static final boolean LIE_ABOUT_AWB_STATE = false;
-    static final boolean LIE_ABOUT_AWB = true;
+    static final boolean LIE_ABOUT_AWB = false;
 
     /**
      * Create characteristics for a legacy device by mapping the {@code parameters}
@@ -436,8 +436,52 @@
     }
 
     private static void mapControlAwb(CameraMetadataNative m, Camera.Parameters p) {
-        if (!LIE_ABOUT_AWB) {
-            throw new AssertionError("Not implemented yet");
+        /*
+         * control.awbAvailableModes
+         */
+
+        {
+            List<String> wbModes = p.getSupportedWhiteBalance();
+
+            String[] wbModeStrings = new String[] {
+                    Camera.Parameters.WHITE_BALANCE_AUTO                    ,
+                    Camera.Parameters.WHITE_BALANCE_INCANDESCENT            ,
+                    Camera.Parameters.WHITE_BALANCE_FLUORESCENT             ,
+                    Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT        ,
+                    Camera.Parameters.WHITE_BALANCE_DAYLIGHT                ,
+                    Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT         ,
+                    Camera.Parameters.WHITE_BALANCE_TWILIGHT                ,
+                    Camera.Parameters.WHITE_BALANCE_SHADE                   ,
+            };
+
+            int[] wbModeInts = new int[] {
+                    CONTROL_AWB_MODE_AUTO,
+                    CONTROL_AWB_MODE_INCANDESCENT            ,
+                    CONTROL_AWB_MODE_FLUORESCENT             ,
+                    CONTROL_AWB_MODE_WARM_FLUORESCENT        ,
+                    CONTROL_AWB_MODE_DAYLIGHT                ,
+                    CONTROL_AWB_MODE_CLOUDY_DAYLIGHT         ,
+                    CONTROL_AWB_MODE_TWILIGHT                ,
+                    CONTROL_AWB_MODE_SHADE                   ,
+                    // Note that CONTROL_AWB_MODE_OFF is unsupported
+            };
+
+            List<Integer> awbAvail = ArrayUtils.convertStringListToIntList(
+                        wbModes, wbModeStrings, wbModeInts);
+
+            // No AWB modes supported? That's unpossible!
+            if (awbAvail == null || awbAvail.size() == 0) {
+                Log.w(TAG, "No AWB modes supported (HAL bug); defaulting to AWB_MODE_AUTO only");
+                awbAvail = new ArrayList<Integer>(/*capacity*/1);
+                awbAvail.add(CONTROL_AWB_MODE_AUTO);
+            }
+
+            m.set(CONTROL_AWB_AVAILABLE_MODES, ArrayUtils.toIntArray(awbAvail));
+
+            if (VERBOSE) {
+                Log.v(TAG, "mapControlAwb - control.awbAvailableModes set to " +
+                        ListUtils.listToString(awbAvail));
+            }
         }
     }
 
@@ -650,6 +694,11 @@
         m.set(REQUEST_MAX_NUM_INPUT_STREAMS, REQUEST_MAX_NUM_INPUT_STREAMS_COUNT);
 
         /*
+         * request.partialResultCount
+         */
+        m.set(REQUEST_PARTIAL_RESULT_COUNT, 1); // No partial results supported
+
+        /*
          * request.pipelineMaxDepth
          */
         m.set(REQUEST_PIPELINE_MAX_DEPTH,
@@ -680,6 +729,14 @@
         }
 
         /*
+         * sensor.availableTestPatternModes
+         */
+        {
+            // Only "OFF" test pattern mode is available
+            m.set(SENSOR_AVAILABLE_TEST_PATTERN_MODES, new int[] { SENSOR_TEST_PATTERN_MODE_OFF });
+        }
+
+        /*
          * sensor.info.pixelArraySize
          */
         m.set(SENSOR_INFO_PIXEL_ARRAY_SIZE, largestJpegSize);
@@ -921,11 +978,9 @@
          * control.*
          */
 
-        if (LIE_ABOUT_AWB) {
-            m.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_AUTO);
-        } else {
-            throw new AssertionError("Valid control.awbMode not implemented yet");
-        }
+        // control.awbMode
+        m.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_AUTO);
+        // AWB is always unconditionally available in API1 devices
 
         // control.aeAntibandingMode
         m.set(CaptureRequest.CONTROL_AE_ANTIBANDING_MODE, CONTROL_AE_ANTIBANDING_MODE_AUTO);
diff --git a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java b/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java
index dfec9008..a6fe035 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java
@@ -216,6 +216,25 @@
             }
         }
 
+        // control.awbMode
+        {
+            Integer awbMode = getIfSupported(request, CONTROL_AWB_MODE,
+                    /*defaultValue*/CONTROL_AWB_MODE_AUTO,
+                    params.getSupportedWhiteBalance() != null,
+                    /*allowedValue*/CONTROL_AWB_MODE_AUTO);
+
+            String whiteBalanceMode = null;
+            if (awbMode != null) { // null iff AWB is not supported by camera1 api
+                whiteBalanceMode = convertAwbModeToLegacy(awbMode);
+                params.setWhiteBalance(whiteBalanceMode);
+            }
+
+            if (VERBOSE) {
+                Log.v(TAG, "convertRequestToMetadata - control.awbMode "
+                        + awbMode + " mapped to " + whiteBalanceMode);
+            }
+        }
+
         // control.awbLock
         {
             Boolean awbLock = getIfSupported(request, CONTROL_AWB_LOCK, /*defaultValue*/false,
@@ -294,6 +313,20 @@
                 }
             }
         }
+
+        /*
+         * sensor
+         */
+
+        // sensor.testPattern
+        {
+            int testPatternMode = ParamsUtils.getOrDefault(request, SENSOR_TEST_PATTERN_MODE,
+                    /*defaultValue*/SENSOR_TEST_PATTERN_MODE_OFF);
+            if (testPatternMode != SENSOR_TEST_PATTERN_MODE_OFF) {
+                Log.w(TAG, "convertRequestToMetadata - ignoring sensor.testPatternMode "
+                        + testPatternMode + "; only OFF is supported");
+            }
+        }
     }
 
     private static List<Camera.Area> convertMeteringRegionsToLegacy(
@@ -445,6 +478,29 @@
         return legacyFps;
     }
 
+    private static String convertAwbModeToLegacy(int mode) {
+        switch (mode) {
+            case CONTROL_AWB_MODE_AUTO:
+                return Camera.Parameters.WHITE_BALANCE_AUTO;
+            case CONTROL_AWB_MODE_INCANDESCENT:
+                return Camera.Parameters.WHITE_BALANCE_INCANDESCENT;
+            case CONTROL_AWB_MODE_FLUORESCENT:
+                return Camera.Parameters.WHITE_BALANCE_FLUORESCENT;
+            case CONTROL_AWB_MODE_WARM_FLUORESCENT:
+                return Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT;
+            case CONTROL_AWB_MODE_DAYLIGHT:
+                return Camera.Parameters.WHITE_BALANCE_DAYLIGHT;
+            case CONTROL_AWB_MODE_CLOUDY_DAYLIGHT:
+                return Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT;
+            case CONTROL_AWB_MODE_TWILIGHT:
+                return Camera.Parameters.WHITE_BALANCE_TWILIGHT;
+            default:
+                Log.w(TAG, "convertAwbModeToLegacy - unrecognized control.awbMode" + mode);
+                return Camera.Parameters.WHITE_BALANCE_AUTO;
+        }
+    }
+
+
     /**
      * Return {@code null} if the value is not supported, otherwise return the retrieved key's
      * value from the request (or the default value if it wasn't set).
diff --git a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
index 6da5dd0..9eff943 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
@@ -20,7 +20,6 @@
 import android.hardware.Camera;
 import android.hardware.Camera.Parameters;
 import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraMetadata;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
 import android.hardware.camera2.impl.CameraMetadataNative;
@@ -133,26 +132,15 @@
          */
         mapAe(result, characteristics, request, activeArraySize, zoomData, /*out*/params);
 
-        // control.afMode
-        result.set(CaptureResult.CONTROL_AF_MODE, convertLegacyAfMode(params.getFocusMode()));
+        /*
+         * control.af*
+         */
+        mapAf(result, activeArraySize, zoomData, /*out*/params);
 
-        // control.awbLock
-        result.set(CaptureResult.CONTROL_AWB_LOCK, params.getAutoWhiteBalanceLock());
-
-        // control.awbState
-        if (LegacyMetadataMapper.LIE_ABOUT_AWB_STATE) {
-            // Lie to pass CTS temporarily.
-            // TODO: CTS needs to be updated not to query this value
-            // for LIMITED devices unless its guaranteed to be available.
-            result.set(CaptureResult.CONTROL_AWB_STATE,
-                    CameraMetadata.CONTROL_AWB_STATE_CONVERGED);
-            // TODO: Read the awb mode from parameters instead
-        }
-
-        if (LegacyMetadataMapper.LIE_ABOUT_AWB) {
-            result.set(CaptureResult.CONTROL_AWB_MODE,
-                    request.get(CaptureRequest.CONTROL_AWB_MODE));
-        }
+        /*
+         * control.awb*
+         */
+        mapAwb(result, /*out*/params);
 
 
         /*
@@ -203,7 +191,7 @@
          * flash
          */
         {
-            // TODO
+            // flash.mode, flash.state mapped in mapAeAndFlashMode
         }
 
         /*
@@ -234,6 +222,11 @@
         /*
          * sensor
          */
+        // sensor.timestamp varies every frame; mapping is done in #cachedConvertResultMetadata
+        {
+            // Unconditionally no test patterns
+            result.set(SENSOR_TEST_PATTERN_MODE, SENSOR_TEST_PATTERN_MODE_OFF);
+        }
 
         // TODO: Remaining result metadata tags conversions.
         return result;
@@ -295,6 +288,13 @@
             m.set(CONTROL_AE_REGIONS, meteringRectArray);
         }
 
+    }
+
+    private static void mapAf(CameraMetadataNative m,
+            Rect activeArray, ZoomData zoomData, Camera.Parameters p) {
+        // control.afMode
+        m.set(CaptureResult.CONTROL_AF_MODE, convertLegacyAfMode(p.getFocusMode()));
+
         // control.afRegions
         {
             if (VERBOSE) {
@@ -307,13 +307,21 @@
 
             m.set(CONTROL_AF_REGIONS, meteringRectArray);
         }
+    }
 
+    private static void mapAwb(CameraMetadataNative m, Camera.Parameters p) {
         // control.awbLock
         {
             boolean lock = p.isAutoWhiteBalanceLockSupported() ?
                     p.getAutoWhiteBalanceLock() : false;
             m.set(CONTROL_AWB_LOCK, lock);
         }
+
+        // control.awbMode
+        {
+            int awbMode = convertLegacyAwbMode(p.getWhiteBalance());
+            m.set(CONTROL_AWB_MODE, awbMode);
+        }
     }
 
     private static MeteringRectangle[] getMeteringRectangles(Rect activeArray, ZoomData zoomData,
@@ -412,6 +420,35 @@
         }
     }
 
+    private static int convertLegacyAwbMode(String mode) {
+        if (mode == null) {
+            // OK: camera1 api may not support changing WB modes; assume AUTO
+            return CONTROL_AWB_MODE_AUTO;
+        }
+
+        switch (mode) {
+            case Camera.Parameters.WHITE_BALANCE_AUTO:
+                return CONTROL_AWB_MODE_AUTO;
+            case Camera.Parameters.WHITE_BALANCE_INCANDESCENT:
+                return CONTROL_AWB_MODE_INCANDESCENT;
+            case Camera.Parameters.WHITE_BALANCE_FLUORESCENT:
+                return CONTROL_AWB_MODE_FLUORESCENT;
+            case Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT:
+                return CONTROL_AWB_MODE_WARM_FLUORESCENT;
+            case Camera.Parameters.WHITE_BALANCE_DAYLIGHT:
+                return CONTROL_AWB_MODE_DAYLIGHT;
+            case Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT:
+                return CONTROL_AWB_MODE_CLOUDY_DAYLIGHT;
+            case Camera.Parameters.WHITE_BALANCE_TWILIGHT:
+                return CONTROL_AWB_MODE_TWILIGHT;
+            case Camera.Parameters.WHITE_BALANCE_SHADE:
+                return CONTROL_AWB_MODE_SHADE;
+            default:
+                Log.w(TAG, "convertAwbMode - unrecognized WB mode " + mode);
+                return CONTROL_AWB_MODE_AUTO;
+        }
+    }
+
     /** Map results for scaler.* */
     private static void mapScaler(CameraMetadataNative m,
             ZoomData zoomData,
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 1b9a0c5..8b44f3b 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -416,6 +416,15 @@
         }
     }
 
+    public void resizeVirtualDisplay(IVirtualDisplayCallbacks token,
+            int width, int height, int densityDpi) {
+        try {
+            mDm.resizeVirtualDisplay(token, width, height, densityDpi);
+        } catch (RemoteException ex) {
+            Log.w(TAG, "Failed to resize virtual display.", ex);
+        }
+    }
+
     public void releaseVirtualDisplay(IVirtualDisplayCallbacks token) {
         try {
             mDm.releaseVirtualDisplay(token);
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 99af2e7..8447dde 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -106,21 +106,30 @@
     public abstract void performTraversalInTransactionFromWindowManager();
 
     /**
-     * Tells the display manager whether there is interesting unique content on the
-     * specified logical display.  This is used to control automatic mirroring.
+     * Tells the display manager about properties of the display that depend on the windows on it.
+     * This includes whether there is interesting unique content on the specified logical display,
+     * and whether the one of the windows has a preferred refresh rate.
      * <p>
      * If the display has unique content, then the display manager arranges for it
      * to be presented on a physical display if appropriate.  Otherwise, the display manager
      * may choose to make the physical display mirror some other logical display.
      * </p>
      *
+     * <p>
+     * If one of the windows on the display has a preferred refresh rate that's supported by the
+     * display, then the display manager will request its use.
+     * </p>
+     *
      * @param displayId The logical display id to update.
-     * @param hasContent True if the logical display has content.
+     * @param hasContent True if the logical display has content. This is used to control automatic
+     * mirroring.
+     * @param requestedRefreshRate The preferred refresh rate for the top-most visible window that
+     * has a preference.
      * @param inTraversal True if called from WindowManagerService during a window traversal
      * prior to call to performTraversalInTransactionFromWindowManager.
      */
-    public abstract void setDisplayHasContent(int displayId, boolean hasContent,
-            boolean inTraversal);
+    public abstract void setDisplayProperties(int displayId, boolean hasContent,
+            float requestedRefreshRate, boolean inTraversal);
 
     /**
      * Describes the requested power state of the display.
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index 44ffbc4..cfaa5a0 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -65,6 +65,10 @@
             in IMediaProjection projectionToken, String packageName, String name,
             int width, int height, int densityDpi, in Surface surface, int flags);
 
+    // No permissions required, but must be same Uid as the creator.
+    void resizeVirtualDisplay(in IVirtualDisplayCallbacks token,
+            int width, int height, int densityDpi);
+
     // No permissions required but must be same Uid as the creator.
     void setVirtualDisplaySurface(in IVirtualDisplayCallbacks token, in Surface surface);
 
diff --git a/core/java/android/hardware/display/VirtualDisplay.java b/core/java/android/hardware/display/VirtualDisplay.java
index df6116b..1dd6978 100644
--- a/core/java/android/hardware/display/VirtualDisplay.java
+++ b/core/java/android/hardware/display/VirtualDisplay.java
@@ -80,6 +80,18 @@
     }
 
     /**
+     * Asks the virtual display to resize.
+     *<p>
+     * This is really just a convenience to allow applications using
+     * virtual displays to adapt to changing conditions without having
+     * to tear down and recreate the display.
+     * </p>
+     */
+    public void resize(int width, int height, int densityDpi) {
+        mGlobal.resizeVirtualDisplay(mToken, width, height, densityDpi);
+    }
+
+    /**
      * Releases the virtual display and destroys its underlying surface.
      * <p>
      * All remaining windows on the virtual display will be forcibly removed
diff --git a/core/java/android/hardware/hdmi/HdmiCecDeviceInfo.java b/core/java/android/hardware/hdmi/HdmiCecDeviceInfo.java
deleted file mode 100644
index 6e1844a..0000000
--- a/core/java/android/hardware/hdmi/HdmiCecDeviceInfo.java
+++ /dev/null
@@ -1,273 +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.hardware.hdmi;
-
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * A class to encapsulate device information for HDMI-CEC. This container
- * include basic information such as logical address, physical address and
- * device type, and additional information like vendor id and osd name.
- * Also used to keep the information of non-CEC devices for which only
- * port ID, physical address are meaningful.
- *
- * @hide
- */
-@SystemApi
-public final class HdmiCecDeviceInfo implements Parcelable {
-
-    /** TV device type. */
-    public static final int DEVICE_TV = 0;
-
-    /** Recording device type. */
-    public static final int DEVICE_RECORDER = 1;
-
-    /** Device type reserved for future usage. */
-    public static final int DEVICE_RESERVED = 2;
-
-    /** Tuner device type. */
-    public static final int DEVICE_TUNER = 3;
-
-    /** Playback device type. */
-    public static final int DEVICE_PLAYBACK = 4;
-
-    /** Audio system device type. */
-    public static final int DEVICE_AUDIO_SYSTEM = 5;
-
-    /** @hide Pure CEC switch device type. */
-    public static final int DEVICE_PURE_CEC_SWITCH = 6;
-
-    /** @hide Video processor device type. */
-    public static final int DEVICE_VIDEO_PROCESSOR = 7;
-
-    // Value indicating the device is not an active source.
-    public static final int DEVICE_INACTIVE = -1;
-
-    /**
-     * Logical address used to indicate the source comes from internal device.
-     * The logical address of TV(0) is used.
-     */
-    public static final int ADDR_INTERNAL = 0;
-
-    /**
-     * Physical address used to indicate the source comes from internal device.
-     * The physical address of TV(0) is used.
-     */
-    public static final int PATH_INTERNAL = 0x0000;
-
-    /** Invalid physical address (routing path) */
-    public static final int PATH_INVALID = 0xFFFF;
-
-    /** Invalid port ID */
-    public static final int PORT_INVALID = -1;
-
-    // Logical address, physical address, device type, vendor id and display name
-    // are immutable value.
-    private final int mLogicalAddress;
-    private final int mPhysicalAddress;
-    private final int mPortId;
-    private final int mDeviceType;
-    private final int mVendorId;
-    private final String mDisplayName;
-    private final boolean mIsCecDevice;
-
-    /**
-     * A helper class to deserialize {@link HdmiCecDeviceInfo} for a parcel.
-     */
-    public static final Parcelable.Creator<HdmiCecDeviceInfo> CREATOR =
-            new Parcelable.Creator<HdmiCecDeviceInfo>() {
-                @Override
-                public HdmiCecDeviceInfo createFromParcel(Parcel source) {
-                    int logicalAddress = source.readInt();
-                    int physicalAddress = source.readInt();
-                    int portId = source.readInt();
-                    int deviceType = source.readInt();
-                    int vendorId = source.readInt();
-                    String displayName = source.readString();
-                    return new HdmiCecDeviceInfo(logicalAddress, physicalAddress, portId,
-                            deviceType, vendorId, displayName);
-                }
-
-                @Override
-                public HdmiCecDeviceInfo[] newArray(int size) {
-                    return new HdmiCecDeviceInfo[size];
-                }
-            };
-
-    /**
-     * Constructor. Used to initialize the instance for CEC device.
-     *
-     * @param logicalAddress logical address of HDMI-CEC device
-     * @param physicalAddress physical address of HDMI-CEC device
-     * @param portId HDMI port ID (1 for HDMI1)
-     * @param deviceType type of device
-     * @param vendorId vendor id of device. Used for vendor specific command.
-     * @param displayName name of device
-     * @hide
-     */
-    public HdmiCecDeviceInfo(int logicalAddress, int physicalAddress, int portId, int deviceType,
-            int vendorId, String displayName) {
-        mLogicalAddress = logicalAddress;
-        mPhysicalAddress = physicalAddress;
-        mPortId = portId;
-        mDeviceType = deviceType;
-        mDisplayName = displayName;
-        mVendorId = vendorId;
-        mIsCecDevice = true;
-    }
-
-    /**
-     * Constructor. Used to initialize the instance for non-CEC device.
-     *
-     * @param physicalAddress physical address of HDMI device
-     * @param portId HDMI port ID (1 for HDMI1)
-     * @hide
-     */
-    public HdmiCecDeviceInfo(int physicalAddress, int portId) {
-        mLogicalAddress = -1;
-        mPhysicalAddress = physicalAddress;
-        mPortId = portId;
-        mDeviceType = DEVICE_RESERVED;
-        mDisplayName = null;
-        mVendorId = 0;
-        mIsCecDevice = false;
-    }
-
-    /**
-     * Return the logical address of the device.
-     */
-    public int getLogicalAddress() {
-        return mLogicalAddress;
-    }
-
-    /**
-     * Return the physical address of the device.
-     */
-    public int getPhysicalAddress() {
-        return mPhysicalAddress;
-    }
-
-    /**
-     * Return the port ID.
-     */
-    public int getPortId() {
-        return mPortId;
-    }
-
-    /**
-     * Return type of the device. For more details, refer constants between
-     * {@link DEVICE_TV} and {@link DEVICE_INACTIVE}.
-     */
-    public int getDeviceType() {
-        return mDeviceType;
-    }
-
-    /**
-     * Return {@code true} if the device is of a type that can be an input source.
-     */
-    public boolean isSourceType() {
-        return mDeviceType == DEVICE_PLAYBACK
-                || mDeviceType == DEVICE_RECORDER
-                || mDeviceType == DEVICE_TUNER;
-    }
-
-    /**
-     * Return {@code true} if the device represents an HDMI-CEC device. {@code false}
-     * if the device is either MHL or non-CEC device.
-     */
-    public boolean isCecDevice() {
-        return mIsCecDevice;
-    }
-
-    /**
-     * Return display (OSD) name of the device.
-     */
-    public String getDisplayName() {
-        return mDisplayName;
-    }
-
-    /**
-     * Return vendor id of the device. Vendor id is used to distinguish devices
-     * built by other manufactures. This is required for vendor-specific command
-     * on CEC standard.
-     */
-    public int getVendorId() {
-        return mVendorId;
-    }
-
-    /**
-     * Describe the kinds of special objects contained in this Parcelable's
-     * marshalled representation.
-     */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * Serialize this object into a {@link Parcel}.
-     *
-     * @param dest The Parcel in which the object should be written.
-     * @param flags Additional flags about how the object should be written.
-     *        May be 0 or {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE}.
-     */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mLogicalAddress);
-        dest.writeInt(mPhysicalAddress);
-        dest.writeInt(mPortId);
-        dest.writeInt(mDeviceType);
-        dest.writeInt(mVendorId);
-        dest.writeString(mDisplayName);
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer s = new StringBuffer();
-        if (isCecDevice()) {
-            s.append("CEC: ");
-            s.append("logical_address: ").append(mLogicalAddress).append(", ");
-            s.append("physical_address: ").append(mPhysicalAddress).append(", ");
-            s.append("port_id: ").append(mPortId).append(", ");
-            s.append("device_type: ").append(mDeviceType).append(", ");
-            s.append("vendor_id: ").append(mVendorId).append(", ");
-            s.append("display_name: ").append(mDisplayName);
-        } else {
-            s.append("Non-CEC: ");
-            s.append("physical_address: ").append(mPhysicalAddress).append(", ");
-            s.append("port_id: ").append(mPortId).append(", ");
-        }
-        return s.toString();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof HdmiCecDeviceInfo)) {
-            return false;
-        }
-
-        HdmiCecDeviceInfo other = (HdmiCecDeviceInfo) obj;
-        return mLogicalAddress == other.mLogicalAddress
-                && mPhysicalAddress == other.mPhysicalAddress
-                && mPortId == other.mPortId
-                && mDeviceType == other.mDeviceType
-                && mVendorId == other.mVendorId
-                && mDisplayName.equals(other.mDisplayName);
-    }
-}
diff --git a/core/java/android/hardware/hdmi/HdmiClient.java b/core/java/android/hardware/hdmi/HdmiClient.java
index c43e21a..f95ed0f 100644
--- a/core/java/android/hardware/hdmi/HdmiClient.java
+++ b/core/java/android/hardware/hdmi/HdmiClient.java
@@ -1,5 +1,6 @@
 package android.hardware.hdmi;
 
+import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.hardware.hdmi.HdmiControlManager.VendorCommandListener;
 import android.hardware.hdmi.IHdmiVendorCommandListener;
@@ -25,6 +26,21 @@
     }
 
     /**
+     * Returns the active source information.
+     *
+     * @return {@link HdmiDeviceInfo} object that describes the active source
+     *         or active routing path
+     */
+    public HdmiDeviceInfo getActiveSource() {
+        try {
+            return mService.getActiveSource();
+        } catch (RemoteException e) {
+            Log.e(TAG, "getActiveSource threw exception ", e);
+        }
+        return null;
+    }
+
+    /**
      * Send a key event to other logical device.
      *
      * @param keyCode key code to send. Defined in {@link android.view.KeyEvent}.
@@ -60,7 +76,10 @@
      *
      * @param listener listener object
      */
-    public void addVendorCommandListener(VendorCommandListener listener) {
+    public void addVendorCommandListener(@NonNull VendorCommandListener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("listener cannot be null");
+        }
         try {
             mService.addVendorCommandListener(getListenerWrapper(listener), getDeviceType());
         } catch (RemoteException e) {
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index 55db1df..7cfa211 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -42,7 +42,7 @@
      * Broadcast Action: Display OSD message.
      * <p>Send when the service has a message to display on screen for events
      * that need user's attention such as ARC status change.
-     * <p>Always contains the extra fields {@link #EXTRA_MESSAGE}.
+     * <p>Always contains the extra fields {@link #EXTRA_MESSAGE_ID}.
      * <p>Requires {@link android.Manifest.permission#HDMI_CEC} to receive.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@@ -141,13 +141,71 @@
     /** Timer recording type for external source. */
     public static final int TIMER_RECORDING_TYPE_EXTERNAL = 3;
 
+    // --- Timer Status Data
+    /** [Timer Status Data/Media Info] - Media present and not protected. */
+    public static final int TIMER_STATUS_MEDIA_INFO_PRESENT_NOT_PROTECTED = 0x0;
+    /** [Timer Status Data/Media Info] - Media present, but protected. */
+    public static final int TIMER_STATUS_MEDIA_INFO_PRESENT_PROTECTED = 0x1;
+    /** [Timer Status Data/Media Info] - Media not present. */
+    public static final int TIMER_STATUS_MEDIA_INFO_NOT_PRESENT = 0x2;
+
+    /** [Timer Status Data/Programmed Info] - Enough space available for recording. */
+    public static final int TIMER_STATUS_PROGRAMMED_INFO_ENOUGH_SPACE = 0x8;
+    /** [Timer Status Data/Programmed Info] - Not enough space available for recording. */
+    public static final int TIMER_STATUS_PROGRAMMED_INFO_NOT_ENOUGH_SPACE = 0x9;
+    /** [Timer Status Data/Programmed Info] - Might not enough space available for recording. */
+    public static final int TIMER_STATUS_PROGRAMMED_INFO_MIGHT_NOT_ENOUGH_SPACE = 0xB;
+    /** [Timer Status Data/Programmed Info] - No media info available. */
+    public static final int TIMER_STATUS_PROGRAMMED_INFO_NO_MEDIA_INFO = 0xA;
+
+    /** [Timer Status Data/Not Programmed Error Info] - No free timer available. */
+    public static final int TIMER_STATUS_NOT_PROGRAMMED_NO_FREE_TIME = 0x1;
+    /** [Timer Status Data/Not Programmed Error Info] - Date out of range. */
+    public static final int TIMER_STATUS_NOT_PROGRAMMED_DATE_OUT_OF_RANGE = 0x2;
+    /** [Timer Status Data/Not Programmed Error Info] - Recording Sequence error. */
+    public static final int TIMER_STATUS_NOT_PROGRAMMED_INVALID_SEQUENCE = 0x3;
+    /** [Timer Status Data/Not Programmed Error Info] - Invalid External Plug Number. */
+    public static final int TIMER_STATUS_NOT_PROGRAMMED_INVALID_EXTERNAL_PLUG_NUMBER = 0x4;
+    /** [Timer Status Data/Not Programmed Error Info] - Invalid External Physical Address. */
+    public static final int TIMER_STATUS_NOT_PROGRAMMED_INVALID_EXTERNAL_PHYSICAL_NUMBER = 0x5;
+    /** [Timer Status Data/Not Programmed Error Info] - CA system not supported. */
+    public static final int TIMER_STATUS_NOT_PROGRAMMED_CA_NOT_SUPPORTED = 0x6;
+    /** [Timer Status Data/Not Programmed Error Info] - No or insufficient CA Entitlements. */
+    public static final int TIMER_STATUS_NOT_PROGRAMMED_NO_CA_ENTITLEMENTS = 0x7;
+    /** [Timer Status Data/Not Programmed Error Info] - Does not support resolution. */
+    public static final int TIMER_STATUS_NOT_PROGRAMMED_UNSUPPORTED_RESOLUTION = 0x8;
+    /** [Timer Status Data/Not Programmed Error Info] - Parental Lock On. */
+    public static final int TIMER_STATUS_NOT_PROGRAMMED_PARENTAL_LOCK_ON= 0x9;
+    /** [Timer Status Data/Not Programmed Error Info] - Clock Failure. */
+    public static final int TIMER_STATUS_NOT_PROGRAMMED_CLOCK_FAILURE = 0xA;
+    /** [Timer Status Data/Not Programmed Error Info] - Duplicate: already programmed. */
+    public static final int TIMER_STATUS_NOT_PROGRAMMED_DUPLICATED = 0xE;
+
     // --- Extra result value for timer recording.
+    /** No extra error. */
+    public static final int TIMER_RECORDING_RESULT_EXTRA_NO_ERROR = 0x00;
     /** No timer recording - check recorder and connection. */
-    public static final int TIME_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION = 0x01;
+    public static final int TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION = 0x01;
     /** No timer recording - cannot record selected source. */
-    public static final int TIME_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE = 0x02;
+    public static final int TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE = 0x02;
     /** CEC is disabled. */
-    public static final int TIME_RECORDING_RESULT_EXTRA_CEC_DISABLED = 0x33;
+    public static final int TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED = 0x03;
+
+    // -- Timer cleared status data code used for result of onClearTimerRecordingResult.
+    /** Timer not cleared – recording. */
+    public static final int CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_RECORDING = 0x00;
+    /** Timer not cleared – no matching. */
+    public static final int CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_NO_MATCHING = 0x01;
+    /** Timer not cleared – no info available. */
+    public static final int CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_NO_INFO_AVAILABLE = 0x02;
+    /** Timer cleared. */
+    public static final int CLEAR_TIMER_STATUS_TIMER_CLEARED = 0x80;
+    /** Clear timer error - check recorder and connection. */
+    public static final int CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION = 0xA0;
+    /** Clear timer error - cannot clear timer for selected source. */
+    public static final int CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE = 0xA1;
+    /** Clear timer error - CEC is disabled. */
+    public static final int CLEAR_TIMER_STATUS_CEC_DISABLE = 0xA2;
 
     // True if we have a logical device of type playback hosted in the system.
     private final boolean mHasPlaybackDevice;
@@ -170,8 +228,8 @@
                 // Do nothing.
             }
         }
-        mHasTvDevice = hasDeviceType(types, HdmiCecDeviceInfo.DEVICE_TV);
-        mHasPlaybackDevice = hasDeviceType(types, HdmiCecDeviceInfo.DEVICE_PLAYBACK);
+        mHasTvDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_TV);
+        mHasPlaybackDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_PLAYBACK);
     }
 
     private static boolean hasDeviceType(int[] types, int type) {
@@ -187,7 +245,30 @@
     }
 
     /**
-     * Gets an object that represents a HDMI-CEC logical device of type playback on the system.
+     * Gets an object that represents an HDMI-CEC logical device of a specified type.
+     *
+     * @param type CEC device type
+     * @return {@link HdmiClient} instance. {@code null} on failure.
+     * See {@link HdmiDeviceInfo#DEVICE_PLAYBACK}
+     * See {@link HdmiDeviceInfo#DEVICE_TV}
+     */
+    @Nullable
+    public HdmiClient getClient(int type) {
+        if (mService == null) {
+            return null;
+        }
+        switch (type) {
+            case HdmiDeviceInfo.DEVICE_TV:
+                return mHasTvDevice ? new HdmiTvClient(mService) : null;
+            case HdmiDeviceInfo.DEVICE_PLAYBACK:
+                return mHasPlaybackDevice ? new HdmiPlaybackClient(mService) : null;
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Gets an object that represents an HDMI-CEC logical device of type playback on the system.
      *
      * <p>Used to send HDMI control messages to other devices like TV or audio amplifier through
      * HDMI bus. It is also possible to communicate with other logical devices hosted in the same
@@ -197,14 +278,11 @@
      */
     @Nullable
     public HdmiPlaybackClient getPlaybackClient() {
-        if (mService == null || !mHasPlaybackDevice) {
-            return null;
-        }
-        return new HdmiPlaybackClient(mService);
+        return (HdmiPlaybackClient) getClient(HdmiDeviceInfo.DEVICE_PLAYBACK);
     }
 
     /**
-     * Gets an object that represents a HDMI-CEC logical device of type TV on the system.
+     * Gets an object that represents an HDMI-CEC logical device of type TV on the system.
      *
      * <p>Used to send HDMI control messages to other devices and manage them through
      * HDMI bus. It is also possible to communicate with other logical devices hosted in the same
@@ -214,10 +292,7 @@
      */
     @Nullable
     public HdmiTvClient getTvClient() {
-        if (mService == null || !mHasTvDevice) {
-                return null;
-        }
-        return new HdmiTvClient(mService);
+        return (HdmiTvClient) getClient(HdmiDeviceInfo.DEVICE_TV);
     }
 
     /**
@@ -281,6 +356,7 @@
     private IHdmiHotplugEventListener getHotplugEventListenerWrapper(
             final HotplugEventListener listener) {
         return new IHdmiHotplugEventListener.Stub() {
+            @Override
             public void onReceived(HdmiHotplugEvent event) {
                 listener.onReceived(event);;
             }
diff --git a/core/java/android/hardware/hdmi/HdmiCecDeviceInfo.aidl b/core/java/android/hardware/hdmi/HdmiDeviceInfo.aidl
similarity index 95%
rename from core/java/android/hardware/hdmi/HdmiCecDeviceInfo.aidl
rename to core/java/android/hardware/hdmi/HdmiDeviceInfo.aidl
index 1615910..cb76dc8 100644
--- a/core/java/android/hardware/hdmi/HdmiCecDeviceInfo.aidl
+++ b/core/java/android/hardware/hdmi/HdmiDeviceInfo.aidl
@@ -16,4 +16,4 @@
 
 package android.hardware.hdmi;
 
-parcelable HdmiCecDeviceInfo;
+parcelable HdmiDeviceInfo;
diff --git a/core/java/android/hardware/hdmi/HdmiDeviceInfo.java b/core/java/android/hardware/hdmi/HdmiDeviceInfo.java
new file mode 100644
index 0000000..2391d3a
--- /dev/null
+++ b/core/java/android/hardware/hdmi/HdmiDeviceInfo.java
@@ -0,0 +1,411 @@
+/*
+ * 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.hardware.hdmi;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A class to encapsulate device information for HDMI devices including CEC and MHL. In terms of
+ * CEC, this container includes basic information such as logical address, physical address and
+ * device type, and additional information like vendor id and osd name. In terms of MHL device, this
+ * container includes adopter id and device type. Otherwise, it keeps the information of other type
+ * devices for which only port ID, physical address are meaningful.
+ *
+ * @hide
+ */
+@SystemApi
+public class HdmiDeviceInfo implements Parcelable {
+
+    /** TV device type. */
+    public static final int DEVICE_TV = 0;
+
+    /** Recording device type. */
+    public static final int DEVICE_RECORDER = 1;
+
+    /** Device type reserved for future usage. */
+    public static final int DEVICE_RESERVED = 2;
+
+    /** Tuner device type. */
+    public static final int DEVICE_TUNER = 3;
+
+    /** Playback device type. */
+    public static final int DEVICE_PLAYBACK = 4;
+
+    /** Audio system device type. */
+    public static final int DEVICE_AUDIO_SYSTEM = 5;
+
+    /** @hide Pure CEC switch device type. */
+    public static final int DEVICE_PURE_CEC_SWITCH = 6;
+
+    /** @hide Video processor device type. */
+    public static final int DEVICE_VIDEO_PROCESSOR = 7;
+
+    // Value indicating the device is not an active source.
+    public static final int DEVICE_INACTIVE = -1;
+
+    /**
+     * Logical address used to indicate the source comes from internal device. The logical address
+     * of TV(0) is used.
+     */
+    public static final int ADDR_INTERNAL = 0;
+
+    /**
+     * Physical address used to indicate the source comes from internal device. The physical address
+     * of TV(0) is used.
+     */
+    public static final int PATH_INTERNAL = 0x0000;
+
+    /** Invalid physical address (routing path) */
+    public static final int PATH_INVALID = 0xFFFF;
+
+    /** Invalid port ID */
+    public static final int PORT_INVALID = -1;
+
+    private static final int HDMI_DEVICE_TYPE_OTHER = 0;
+    private static final int HDMI_DEVICE_TYPE_CEC = 1;
+    private static final int HDMI_DEVICE_TYPE_MHL = 2;
+
+    // Common parameters for all device.
+    private final int mHdmiDeviceType;
+    private final int mPhysicalAddress;
+    private final int mPortId;
+
+    // CEC only parameters.
+    private final int mLogicalAddress;
+    private final int mDeviceType;
+    private final int mVendorId;
+    private final String mDisplayName;
+    private final int mDevicePowerStatus;
+
+    // MHL only parameters.
+    private final int mDeviceId;
+    private final int mAdopterId;
+
+    /**
+     * A helper class to deserialize {@link HdmiDeviceInfo} for a parcel.
+     */
+    public static final Parcelable.Creator<HdmiDeviceInfo> CREATOR =
+            new Parcelable.Creator<HdmiDeviceInfo>() {
+                @Override
+                public HdmiDeviceInfo createFromParcel(Parcel source) {
+                    int hdmiDeviceType = source.readInt();
+                    int physicalAddress = source.readInt();
+                    int portId = source.readInt();
+
+                    switch (hdmiDeviceType) {
+                        case HDMI_DEVICE_TYPE_CEC:
+                            int logicalAddress = source.readInt();
+                            int deviceType = source.readInt();
+                            int vendorId = source.readInt();
+                            int powerStatus = source.readInt();
+                            String displayName = source.readString();
+                            return new HdmiDeviceInfo(logicalAddress, physicalAddress, portId,
+                                    deviceType, vendorId, displayName, powerStatus);
+                        case HDMI_DEVICE_TYPE_MHL:
+                            int deviceId = source.readInt();
+                            int adopterId = source.readInt();
+                            return new HdmiDeviceInfo(physicalAddress, portId, adopterId, deviceId);
+                        case HDMI_DEVICE_TYPE_OTHER:
+                            return new HdmiDeviceInfo(physicalAddress, portId);
+                        default:
+                            return null;
+                    }
+                }
+
+                @Override
+                public HdmiDeviceInfo[] newArray(int size) {
+                    return new HdmiDeviceInfo[size];
+                }
+            };
+
+    /**
+     * Constructor. Used to initialize the instance for CEC device.
+     *
+     * @param logicalAddress logical address of HDMI-CEC device
+     * @param physicalAddress physical address of HDMI-CEC device
+     * @param portId HDMI port ID (1 for HDMI1)
+     * @param deviceType type of device
+     * @param vendorId vendor id of device. Used for vendor specific command.
+     * @param displayName name of device
+     * @param powerStatus device power status
+     * @hide
+     */
+    public HdmiDeviceInfo(int logicalAddress, int physicalAddress, int portId, int deviceType,
+            int vendorId, String displayName, int powerStatus) {
+        mHdmiDeviceType = HDMI_DEVICE_TYPE_CEC;
+        mPhysicalAddress = physicalAddress;
+        mPortId = portId;
+
+        mLogicalAddress = logicalAddress;
+        mDeviceType = deviceType;
+        mVendorId = vendorId;
+        mDevicePowerStatus = powerStatus;
+        mDisplayName = displayName;
+
+        mDeviceId = -1;
+        mAdopterId = -1;
+    }
+
+    /**
+     * Constructor. Used to initialize the instance for CEC device.
+     *
+     * @param logicalAddress logical address of HDMI-CEC device
+     * @param physicalAddress physical address of HDMI-CEC device
+     * @param portId HDMI port ID (1 for HDMI1)
+     * @param deviceType type of device
+     * @param vendorId vendor id of device. Used for vendor specific command.
+     * @param displayName name of device
+     * @hide
+     */
+    public HdmiDeviceInfo(int logicalAddress, int physicalAddress, int portId, int deviceType,
+            int vendorId, String displayName) {
+        this(logicalAddress, physicalAddress, portId, deviceType,
+                vendorId, displayName, HdmiControlManager.POWER_STATUS_UNKNOWN);
+    }
+
+    /**
+     * Constructor. Used to initialize the instance for other device.
+     *
+     * @param physicalAddress physical address of HDMI device
+     * @param portId HDMI port ID (1 for HDMI1)
+     * @hide
+     */
+    public HdmiDeviceInfo(int physicalAddress, int portId) {
+        mHdmiDeviceType = HDMI_DEVICE_TYPE_OTHER;
+        mPhysicalAddress = physicalAddress;
+        mPortId = portId;
+
+        mLogicalAddress = -1;
+        mDeviceType = DEVICE_RESERVED;
+        mVendorId = 0;
+        mDevicePowerStatus = HdmiControlManager.POWER_STATUS_UNKNOWN;
+        mDisplayName = "HDMI" + portId;
+
+        mDeviceId = -1;
+        mAdopterId = -1;
+
+    }
+
+    /**
+     * Constructor. Used to initialize the instance for MHL device.
+     *
+     * @param physicalAddress physical address of HDMI device
+     * @param portId portId HDMI port ID (1 for HDMI1)
+     * @param adopterId adopter id of MHL
+     * @param deviceId device id of MHL
+     * @hide
+     */
+    public HdmiDeviceInfo(int physicalAddress, int portId, int adopterId, int deviceId) {
+        mHdmiDeviceType = HDMI_DEVICE_TYPE_MHL;
+        mPhysicalAddress = physicalAddress;
+        mPortId = portId;
+
+        mLogicalAddress = -1;
+        mDeviceType = DEVICE_RESERVED;
+        mVendorId = 0;
+        mDevicePowerStatus = HdmiControlManager.POWER_STATUS_UNKNOWN;
+        mDisplayName = "MHL";
+
+        mDeviceId = adopterId;
+        mAdopterId = deviceId;
+    }
+
+    /**
+     * Return the CEC logical address of the device.
+     */
+    public int getLogicalAddress() {
+        return mLogicalAddress;
+    }
+
+    /**
+     * Return the physical address of the device.
+     */
+    public int getPhysicalAddress() {
+        return mPhysicalAddress;
+    }
+
+    /**
+     * Return the port ID.
+     */
+    public int getPortId() {
+        return mPortId;
+    }
+
+    /**
+     * Return CEC type of the device. For more details, refer constants between {@link #DEVICE_TV}
+     * and {@link #DEVICE_INACTIVE}.
+     */
+    public int getDeviceType() {
+        return mDeviceType;
+    }
+
+    /**
+     * Return device's power status. It should be one of the following values.
+     * <ul>
+     * <li>{@link HdmiControlManager#POWER_STATUS_ON}
+     * <li>{@link HdmiControlManager#POWER_STATUS_STANDBY}
+     * <li>{@link HdmiControlManager#POWER_STATUS_TRANSIENT_TO_ON}
+     * <li>{@link HdmiControlManager#POWER_STATUS_TRANSIENT_TO_STANDBY}
+     * <li>{@link HdmiControlManager#POWER_STATUS_UNKNOWN}
+     * </ul>
+     */
+    public int getDevicePowerStatus() {
+        return mDevicePowerStatus;
+    }
+
+    /**
+     * Return MHL device id. Return -1 for non-MHL device.
+     */
+    public int getDeviceId() {
+        return mDeviceId;
+    }
+
+    /**
+     * Return MHL adopter id. Return -1 for non-MHL device.
+     */
+    public int getAdopterId() {
+        return mAdopterId;
+    }
+
+    /**
+     * Return {@code true} if the device is of a type that can be an input source.
+     */
+    public boolean isSourceType() {
+        return mDeviceType == DEVICE_PLAYBACK
+                || mDeviceType == DEVICE_RECORDER
+                || mDeviceType == DEVICE_TUNER;
+    }
+
+    /**
+     * Return {@code true} if the device represents an HDMI-CEC device. {@code false} if the device
+     * is either MHL or other device.
+     */
+    public boolean isCecDevice() {
+        return mHdmiDeviceType == HDMI_DEVICE_TYPE_CEC;
+    }
+
+    /**
+     * Return {@code true} if the device represents an MHL device. {@code false} if the device is
+     * either CEC or other device.
+     */
+    public boolean isMhlDevice() {
+        return mHdmiDeviceType == HDMI_DEVICE_TYPE_MHL;
+    }
+
+    /**
+     * Return display (OSD) name of the device.
+     */
+    public String getDisplayName() {
+        return mDisplayName;
+    }
+
+    /**
+     * Return vendor id of the device. Vendor id is used to distinguish devices built by other
+     * manufactures. This is required for vendor-specific command on CEC standard.
+     */
+    public int getVendorId() {
+        return mVendorId;
+    }
+
+    /**
+     * Describe the kinds of special objects contained in this Parcelable's marshalled
+     * representation.
+     */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Serialize this object into a {@link Parcel}.
+     *
+     * @param dest The Parcel in which the object should be written.
+     * @param flags Additional flags about how the object should be written. May be 0 or
+     *            {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE}.
+     */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mHdmiDeviceType);
+        dest.writeInt(mPhysicalAddress);
+        dest.writeInt(mPortId);
+        switch (mHdmiDeviceType) {
+            case HDMI_DEVICE_TYPE_CEC:
+                dest.writeInt(mLogicalAddress);
+                dest.writeInt(mDeviceType);
+                dest.writeInt(mVendorId);
+                dest.writeInt(mDevicePowerStatus);
+                dest.writeString(mDisplayName);
+                break;
+            case HDMI_DEVICE_TYPE_MHL:
+                dest.writeInt(mDeviceId);
+                dest.writeInt(mAdopterId);
+                break;
+            default:
+                // no-op
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer s = new StringBuffer();
+        switch (mHdmiDeviceType) {
+            case HDMI_DEVICE_TYPE_CEC:
+                s.append("CEC: ");
+                s.append("logical_address: ").append(mLogicalAddress).append(", ");
+                s.append("device_type: ").append(mDeviceType).append(", ");
+                s.append("vendor_id: ").append(mVendorId).append(", ");
+                s.append("display_name: ").append(mDisplayName).append(", ");
+                s.append("power_status: ").append(mDevicePowerStatus).append(", ");
+                break;
+            case HDMI_DEVICE_TYPE_MHL:
+                s.append("MHL: ");
+                break;
+
+            case HDMI_DEVICE_TYPE_OTHER:
+                s.append("Other: ");
+                s.append("device_id: ").append(mDeviceId).append(", ");
+                s.append("adopter_id: ").append(mAdopterId).append(", ");
+                break;
+            default:
+                return "";
+        }
+        s.append("physical_address: ").append(mPhysicalAddress).append(", ");
+        s.append("port_id: ").append(mPortId);
+        return s.toString();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof HdmiDeviceInfo)) {
+            return false;
+        }
+
+        HdmiDeviceInfo other = (HdmiDeviceInfo) obj;
+        return mHdmiDeviceType == other.mHdmiDeviceType
+                && mPhysicalAddress == other.mPhysicalAddress
+                && mPortId == other.mPortId
+                && mLogicalAddress == other.mLogicalAddress
+                && mDeviceType == other.mDeviceType
+                && mVendorId == other.mVendorId
+                && mDevicePowerStatus == other.mDevicePowerStatus
+                && mDisplayName.equals(other.mDisplayName)
+                && mDeviceId == other.mDeviceId
+                && mAdopterId == other.mAdopterId;
+    }
+}
diff --git a/core/java/android/hardware/hdmi/HdmiPlaybackClient.java b/core/java/android/hardware/hdmi/HdmiPlaybackClient.java
index 74cdc4e..85ccb74 100644
--- a/core/java/android/hardware/hdmi/HdmiPlaybackClient.java
+++ b/core/java/android/hardware/hdmi/HdmiPlaybackClient.java
@@ -52,12 +52,14 @@
         /**
          * Called when display device status is reported.
          *
-         * @param status display device status
-         * @see {@link HdmiControlManager#POWER_STATUS_ON}
-         * @see {@link HdmiControlManager#POWER_STATUS_STANDBY}
-         * @see {@link HdmiControlManager#POWER_STATUS_TRANSIENT_TO_ON}
-         * @see {@link HdmiControlManager#POWER_STATUS_TRANSIENT_TO_STANDBY}
-         * @see {@link HdmiControlManager#POWER_STATUS_UNKNOWN}
+         * @param status display device status. It should be one of the following values.
+         *            <ul>
+         *            <li>{@link HdmiControlManager#POWER_STATUS_ON}
+         *            <li>{@link HdmiControlManager#POWER_STATUS_STANDBY}
+         *            <li>{@link HdmiControlManager#POWER_STATUS_TRANSIENT_TO_ON}
+         *            <li>{@link HdmiControlManager#POWER_STATUS_TRANSIENT_TO_STANDBY}
+         *            <li>{@link HdmiControlManager#POWER_STATUS_UNKNOWN}
+         *            </ul>
          */
         public void onComplete(int status);
     }
@@ -82,8 +84,9 @@
         }
     }
 
+    @Override
     public int getDeviceType() {
-        return HdmiCecDeviceInfo.DEVICE_PLAYBACK;
+        return HdmiDeviceInfo.DEVICE_PLAYBACK;
     }
 
     /**
@@ -93,7 +96,6 @@
      *         of the result
      */
     public void queryDisplayStatus(DisplayStatusCallback callback) {
-        // TODO: PendingResult.
         try {
             mService.queryDisplayStatus(getCallbackWrapper(callback));
         } catch (RemoteException e) {
diff --git a/core/java/android/hardware/hdmi/HdmiRecordListener.java b/core/java/android/hardware/hdmi/HdmiRecordListener.java
index 0b1166b..f6a348a 100644
--- a/core/java/android/hardware/hdmi/HdmiRecordListener.java
+++ b/core/java/android/hardware/hdmi/HdmiRecordListener.java
@@ -53,15 +53,192 @@
     /**
      * Called when timer recording is started or failed during initialization.
      *
-     * @param result The most significant three bytes may contain result of &lt;Timer Status&gt;
-     *        while the least significant byte may have error message like
-     *        {@link HdmiControlManager#TIME_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION}
-     *        or
-     *        {@link HdmiControlManager #TIME_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE}
-     *        . If the least significant byte has non zero value the most significant three bytes
-     *        may have 0 value.
+     * @param data timer status data. For more details, look at {@link TimerStatusData}.
      */
-    // TODO: implement result parser.
-    public void onTimerRecordingResult(int result) {
+    public void onTimerRecordingResult(TimerStatusData data) {
+    }
+
+    /**
+     * [Timer overlap warning] [Media Info] [Timer Programmed Info]
+     * @hide
+     */
+    @SystemApi
+    public static class TimerStatusData {
+        private boolean mOverlapped;
+        private int mMediaInfo;
+        private boolean mProgrammed;
+
+        private int mProgrammedInfo;
+        private int mNotProgrammedError;
+        private int mDurationHour;
+        private int mDurationMinute;
+
+        private int mExtraError;
+
+        static TimerStatusData parseFrom(int result) {
+            TimerStatusData data = new TimerStatusData();
+            // Timer Overlap Warning - 1 bit
+            data.mOverlapped = ((result >> 31) & 0x1) != 0;
+            // Media Info - 2 bits;
+            data.mMediaInfo = (result >> 29) & 0x3;
+            // Programmed Indicator - 1 bit;
+            data.mProgrammed = ((result >> 28) & 0x1) != 0;
+            if (data.mProgrammed) {
+                data.mProgrammedInfo = (result >> 24) & 0xF;
+                data.mDurationHour = bcdByteToInt((byte) ((result >> 16) & 0xFF));
+                data.mDurationMinute = bcdByteToInt((byte) ((result >> 8) & 0xFF));
+            } else {
+                // Programmed Info - 4 bits
+                data.mNotProgrammedError = (result >> 24) & 0xF;
+                data.mDurationHour = bcdByteToInt((byte) ((result >> 16) & 0xFF));
+                data.mDurationMinute = bcdByteToInt((byte) ((result >> 8) & 0xFF));
+            }
+
+            // The last byte is used for extra error.
+            data.mExtraError = result & 0xFF;
+            return data;
+        }
+
+        // Most significant 4 bits is used for 10 digits and
+        // Least significant 4 bits is used for 1 digits.
+        private static int bcdByteToInt(byte value) {
+            return ((value >> 4) & 0xF) * 10 + value & 0xF;
+        }
+
+        private TimerStatusData() {}
+
+        /**
+         * Indicates if there is another timer block already set which overlaps with this new
+         * recording request.
+         */
+        public boolean isOverlapped() {
+            return mOverlapped;
+        }
+
+        /**
+         * Indicates if removable media is present and its write protect state.
+         * It should be one of the following values.
+         * <ul>
+         *   <li>{@link HdmiControlManager#TIMER_STATUS_MEDIA_INFO_PRESENT_NOT_PROTECTED}
+         *   <li>{@link HdmiControlManager#TIMER_STATUS_MEDIA_INFO_PRESENT_PROTECTED}
+         *   <li>{@link HdmiControlManager#TIMER_STATUS_MEDIA_INFO_NOT_PRESENT}
+         * </ul>
+         */
+        public int getMediaInfo() {
+            return mMediaInfo;
+        }
+
+        /**
+         * Selector for [Timer Programmed Info].
+         * If it is {@code true}, {@link #getProgrammedInfo()} would have meaningful value and
+         * ignore result of {@link #getNotProgammedError()}.
+         */
+        public boolean isProgrammed() {
+            return mProgrammed;
+        }
+
+        /**
+         * Information indicating any non-fatal issues with the programming request.
+         * It's set only if {@link #isProgrammed()} returns true.
+         * It should be one of the following values.
+         * <ul>
+         *   <li>{@link HdmiControlManager#TIMER_STATUS_PROGRAMMED_INFO_ENOUGH_SPACE}
+         *   <li>{@link HdmiControlManager#TIMER_STATUS_PROGRAMMED_INFO_NOT_ENOUGH_SPACE}
+         *   <li>{@link HdmiControlManager#TIMER_STATUS_PROGRAMMED_INFO_MIGHT_NOT_ENOUGH_SPACE}
+         *   <li>{@link HdmiControlManager#TIMER_STATUS_PROGRAMMED_INFO_NO_MEDIA_INFO}
+         * </ul>
+         *
+         * @throws IllegalStateException if it's called when {@link #isProgrammed()}
+         *                               returns false
+         */
+        public int getProgrammedInfo() {
+            if (!isProgrammed()) {
+                throw new IllegalStateException(
+                        "No programmed info. Call getNotProgammedError() instead.");
+            }
+            return mProgrammedInfo;
+        }
+
+        /**
+         * Information indicating any fatal issues with the programming request.
+         * It's set only if {@link #isProgrammed()} returns false.
+         * it should be one of the following values.
+         * <ul>
+         *   <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_NO_FREE_TIME}
+         *   <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_DATE_OUT_OF_RANGE}
+         *   <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_INVALID_SEQUENCE}
+         *   <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_INVALID_EXTERNAL_PHYSICAL_NUMBER}
+         *   <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_CA_NOT_SUPPORTED}
+         *   <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_NO_CA_ENTITLEMENTS}
+         *   <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_UNSUPPORTED_RESOLUTION}
+         *   <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_PARENTAL_LOCK_ON}
+         *   <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_CLOCK_FAILURE}
+         *   <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_DUPLICATED}
+         * </ul>
+         *
+         * @throws IllegalStateException if it's called when {@link #isProgrammed()}
+         *                               returns true
+         */
+        public int getNotProgammedError() {
+            if (isProgrammed()) {
+                throw new IllegalStateException(
+                        "Has no not-programmed error. Call getProgrammedInfo() instead.");
+            }
+            return mNotProgrammedError;
+        }
+
+        /**
+         * Duration hours.
+         * Optional parameter: Contains an estimate of the space left on the media, expressed as a
+         * time. This parameter may be returned when:
+         *  - [Programmed Info] is “Not enough space available”; or
+         *  - [Not Programmed Info] is “Duplicate: already programmed”
+         */
+        public int getDurationHour() {
+            return mDurationHour;
+        }
+
+        /**
+         * Duration minutes.
+         * Optional parameter: Contains an estimate of the space left on the media, expressed as a
+         * time. This parameter may be returned when:
+         *  - [Programmed Info] is “Not enough space available”; or
+         *  - [Not Programmed Info] is “Duplicate: already programmed”
+         */
+        public int getDurationMinute() {
+            return mDurationMinute;
+        }
+
+        /**
+         * Extra error code.
+         * <ul>
+         * <li>{@link HdmiControlManager#TIMER_RECORDING_RESULT_EXTRA_NO_ERROR}
+         *     No extra errors. Other values of this class might be available.
+         * <li>{@link HdmiControlManager#TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION}
+         *     Check record connection. Other values of this class should be ignored.
+         * <li>{@link HdmiControlManager#TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE}
+         *     Fail to record selected source. Other values of this class should be ignored.
+         * <li>{@link HdmiControlManager#TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED}
+         *     Cec disabled. Other values of this class should be ignored.
+         * </ul>
+         */
+        public int getExtraError() {
+            return mExtraError;
+        }
+    }
+
+    /**
+     * Called when receiving result for clear timer recording request.
+     *
+     * @param result result of clear timer. It should be one of
+     *            {@link HdmiControlManager#CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_RECORDING}
+     *            {@link HdmiControlManager#CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_NO_MATCHING},
+     *            {@link HdmiControlManager#CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_NO_INFO_AVAILABLE},
+     *            {@link HdmiControlManager#CLEAR_TIMER_STATUS_TIMER_CLEARED},
+     *            {@link HdmiControlManager#CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION},
+     *            {@link HdmiControlManager#CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE},
+     *            {@link HdmiControlManager#CLEAR_TIMER_STATUS_CEC_DISABLE}.
+     */
+    public void onClearTimerRecordingResult(int result) {
     }
 }
diff --git a/core/java/android/hardware/hdmi/HdmiRecordSources.java b/core/java/android/hardware/hdmi/HdmiRecordSources.java
index 917d1d9..dcc41fa 100644
--- a/core/java/android/hardware/hdmi/HdmiRecordSources.java
+++ b/core/java/android/hardware/hdmi/HdmiRecordSources.java
@@ -71,7 +71,7 @@
             return includeType ? mExtraDataSize + 1 : mExtraDataSize;
         }
 
-        public final int toByteArray(boolean includeType, byte[] data, int index) {
+        final int toByteArray(boolean includeType, byte[] data, int index) {
             if (includeType) {
                 // 1 to 8 bytes (depends on source).
                 // {[Record Source Type]} |
@@ -161,7 +161,7 @@
      * Interface for digital source identification.
      */
     private interface DigitalServiceIdentification {
-        void toByteArray(byte[] data, int index);
+        int toByteArray(byte[] data, int index);
     }
 
     /**
@@ -193,8 +193,9 @@
         }
 
         @Override
-        public void toByteArray(byte[] data, int index) {
-            threeFieldsToSixBytes(mTransportStreamId, mServiceId, mOriginalNetworkId, data, index);
+        public int toByteArray(byte[] data, int index) {
+            return threeFieldsToSixBytes(mTransportStreamId, mServiceId, mOriginalNetworkId, data,
+                    index);
         }
     }
 
@@ -221,8 +222,8 @@
         }
 
         @Override
-        public void toByteArray(byte[] data, int index) {
-            threeFieldsToSixBytes(mTransportStreamId, mProgramNumber, 0, data, index);
+        public int toByteArray(byte[] data, int index) {
+            return threeFieldsToSixBytes(mTransportStreamId, mProgramNumber, 0, data, index);
         }
     }
 
@@ -255,8 +256,9 @@
         }
 
         @Override
-        public void toByteArray(byte[] data, int index) {
-            threeFieldsToSixBytes(mTransportStreamId, mServiceId, mOriginalNetworkId, data, index);
+        public int toByteArray(byte[] data, int index) {
+            return threeFieldsToSixBytes(mTransportStreamId, mServiceId, mOriginalNetworkId, data,
+                    index);
         }
     }
 
@@ -283,12 +285,13 @@
             mMinorChannelNumber = minorNumer;
         }
 
-        private void toByteArray(byte[] data, int index) {
+        private int toByteArray(byte[] data, int index) {
             // The first 6 bits for format, the 10 bits for major number.
             data[index] = (byte) (((mChannelNumberFormat << 2) | (mMajorChannelNumber >>> 8) & 0x3));
             data[index + 1] = (byte) (mMajorChannelNumber & 0xFF);
             // Minor number uses the next 16 bits.
             shortToByteArray((short) mMinorChannelNumber, data, index + 2);
+            return 4;
         }
     }
 
@@ -323,11 +326,12 @@
         }
 
         @Override
-        public void toByteArray(byte[] data, int index) {
+        public int toByteArray(byte[] data, int index) {
             mChannelIdentifier.toByteArray(data, index);
             // The last 2 bytes is reserved for future use.
             data[index + 4] = 0;
             data[index + 5] = 0;
+            return 6;
         }
     }
 
diff --git a/core/java/android/hardware/hdmi/HdmiTimerRecordSources.java b/core/java/android/hardware/hdmi/HdmiTimerRecordSources.java
index 01b4dd3..1780707 100644
--- a/core/java/android/hardware/hdmi/HdmiTimerRecordSources.java
+++ b/core/java/android/hardware/hdmi/HdmiTimerRecordSources.java
@@ -142,34 +142,34 @@
     /**
      * Create {@link Duration} for time value.
      *
-     * @param hour hour in range of [0, 24]
+     * @param hour hour in range of [0, 23]
      * @param minute minute in range of [0, 60]
      * @return {@link Duration}
      * @throws IllegalArgumentException if hour or minute is out of range
      */
-    public static Time ofTime(int hour, int minute) {
+    public static Time timeOf(int hour, int minute) {
         checkTimeValue(hour, minute);
         return new Time(hour, minute);
     }
 
     private static void checkTimeValue(int hour, int minute) {
-        if (hour < 0 || hour > 24) {
-            throw new IllegalArgumentException("Hour should be in rage of [0, 24]:" + hour);
+        if (hour < 0 || hour > 23) {
+            throw new IllegalArgumentException("Hour should be in rage of [0, 23]:" + hour);
         }
-        if (minute < 0 || minute > 60) {
-            throw new IllegalArgumentException("Minute should be in rage of [0, 60]:" + minute);
+        if (minute < 0 || minute > 59) {
+            throw new IllegalArgumentException("Minute should be in rage of [0, 59]:" + minute);
         }
     }
 
     /**
      * Create {@link Duration} for duration value.
      *
-     * @param hour hour in range of [0, 90]
-     * @param minute minute in range of [0, 60]
+     * @param hour hour in range of [0, 99]
+     * @param minute minute in range of [0, 59]
      * @return {@link Duration}
      * @throws IllegalArgumentException if hour or minute is out of range
      */
-    public static Duration ofDuration(int hour, int minute) {
+    public static Duration durationOf(int hour, int minute) {
         checkDurationValue(hour, minute);
         return new Duration(hour, minute);
     }
@@ -178,8 +178,8 @@
         if (hour < 0 || hour > 99) {
             throw new IllegalArgumentException("Hour should be in rage of [0, 99]:" + hour);
         }
-        if (minute < 0 || minute > 60) {
-            throw new IllegalArgumentException("minute should be in rage of [0, 60]:" + minute);
+        if (minute < 0 || minute > 59) {
+            throw new IllegalArgumentException("minute should be in rage of [0, 59]:" + minute);
         }
     }
 
@@ -210,7 +210,7 @@
      * @hide
      */
     @SystemApi
-    public static class Time extends TimeUnit {
+    public static final class Time extends TimeUnit {
         private Time(int hour, int minute) {
             super(hour, minute);
         }
@@ -221,7 +221,7 @@
      * @hide
      */
     @SystemApi
-    public static class Duration extends TimeUnit {
+    public static final class Duration extends TimeUnit {
         private Duration(int hour, int minute) {
             super(hour, minute);
         }
@@ -298,7 +298,7 @@
      * @hide
      */
     @SystemApi
-    public static class TimerInfo {
+    public static final class TimerInfo {
         private static final int DAY_OF_MONTH_SIZE = 1;
         private static final int MONTH_OF_YEAR_SIZE = 1;
         private static final int START_TIME_SIZE = 2; // 1byte for hour and 1byte for minute.
@@ -373,7 +373,7 @@
      * @hide
      */
     @SystemApi
-    public static class TimerRecordSource {
+    public static final class TimerRecordSource {
         private final RecordSource mRecordSource;
         private final TimerInfo mTimerInfo;
 
diff --git a/core/java/android/hardware/hdmi/HdmiTvClient.java b/core/java/android/hardware/hdmi/HdmiTvClient.java
index 3436287..a9040cf 100644
--- a/core/java/android/hardware/hdmi/HdmiTvClient.java
+++ b/core/java/android/hardware/hdmi/HdmiTvClient.java
@@ -15,6 +15,7 @@
  */
 package android.hardware.hdmi;
 
+import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.hardware.hdmi.HdmiRecordSources.RecordSource;
 import android.hardware.hdmi.HdmiTimerRecordSources.TimerRecordSource;
@@ -95,7 +96,7 @@
 
     @Override
     public int getDeviceType() {
-        return HdmiCecDeviceInfo.DEVICE_TV;
+        return HdmiDeviceInfo.DEVICE_TV;
     }
 
     /**
@@ -113,11 +114,14 @@
     /**
      * Select a CEC logical device to be a new active source.
      *
-     * @param logicalAddress
-     * @param callback
+     * @param logicalAddress logical address of the device to select
+     * @param callback callback to get the result with
+     * @throws {@link IllegalArgumentException} if the {@code callback} is null
      */
-    public void deviceSelect(int logicalAddress, SelectCallback callback) {
-        // TODO: Replace SelectCallback with PartialResult.
+    public void deviceSelect(int logicalAddress, @NonNull SelectCallback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("callback must not be null.");
+        }
         try {
             mService.deviceSelect(logicalAddress, getCallbackWrapper(callback));
         } catch (RemoteException e) {
@@ -126,6 +130,24 @@
     }
 
     /**
+     * Select a HDMI port to be a new route path.
+     *
+     * @param portId HDMI port to select
+     * @param callback callback to get the result with
+     * @throws {@link IllegalArgumentException} if the {@code callback} is null
+     */
+    public void portSelect(int portId, @NonNull SelectCallback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("Callback must not be null");
+        }
+        try {
+            mService.portSelect(portId, getCallbackWrapper(callback));
+        } catch (RemoteException e) {
+            Log.e(TAG, "failed to select port: ", e);
+        }
+    }
+
+    /**
      * Set system audio volume
      *
      * @param oldIndex current volume index
@@ -158,7 +180,10 @@
      *
      * @param listener
      */
-    public void setRecordListener(HdmiRecordListener listener) {
+    public void setRecordListener(@NonNull HdmiRecordListener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("listener must not be null.");
+        }
         try {
             mService.setHdmiRecordListener(getListenerWrapper(listener));
         } catch (RemoteException e) {
@@ -177,7 +202,11 @@
      * tvClient.startOneTouchRecord(recorderAddress, ownSource);
      * </pre>
      */
-    public void startOneTouchRecord(int recorderAddress, RecordSource source) {
+    public void startOneTouchRecord(int recorderAddress, @NonNull RecordSource source) {
+        if (source == null) {
+            throw new IllegalArgumentException("source must not be null.");
+        }
+
         try {
             byte[] data = new byte[source.getDataSize(true)];
             source.toByteArray(true, data, 0);
@@ -223,6 +252,10 @@
      * @param source record source to be used
      */
     public void startTimerRecording(int recorderAddress, int sourceType, TimerRecordSource source) {
+        if (source == null) {
+            throw new IllegalArgumentException("source must not be null.");
+        }
+
         checkTimerRecordingSourceType(sourceType);
 
         try {
@@ -250,6 +283,10 @@
      * For more details, please refer {@link #startTimerRecording(int, int, TimerRecordSource)}.
      */
     public void clearTimerRecording(int recorderAddress, int sourceType, TimerRecordSource source) {
+        if (source == null) {
+            throw new IllegalArgumentException("source must not be null.");
+        }
+
         checkTimerRecordingSourceType(sourceType);
         try {
             byte[] data = new byte[source.getDataSize()];
@@ -290,7 +327,13 @@
 
             @Override
             public void onTimerRecordingResult(int result) {
-                callback.onTimerRecordingResult(result);
+                callback.onTimerRecordingResult(
+                        HdmiRecordListener.TimerStatusData.parseFrom(result));
+            }
+
+            @Override
+            public void onClearTimerRecordingResult(int result) {
+                callback.onClearTimerRecordingResult(result);
             }
         };
     }
diff --git a/core/java/android/hardware/hdmi/IHdmiControlService.aidl b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
index 920a1f4..d6cb492 100644
--- a/core/java/android/hardware/hdmi/IHdmiControlService.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
@@ -16,7 +16,7 @@
 
 package android.hardware.hdmi;
 
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.HdmiPortInfo;
 import android.hardware.hdmi.IHdmiControlCallback;
 import android.hardware.hdmi.IHdmiDeviceEventListener;
@@ -37,7 +37,7 @@
  */
 interface IHdmiControlService {
     int[] getSupportedTypes();
-    HdmiCecDeviceInfo getActiveSource();
+    HdmiDeviceInfo getActiveSource();
     void oneTouchPlay(IHdmiControlCallback callback);
     void queryDisplayStatus(IHdmiControlCallback callback);
     void addHotplugEventListener(IHdmiHotplugEventListener listener);
@@ -59,7 +59,7 @@
     void setSystemAudioVolume(int oldIndex, int newIndex, int maxIndex);
     void setSystemAudioMute(boolean mute);
     void setInputChangeListener(IHdmiInputChangeListener listener);
-    List<HdmiCecDeviceInfo> getInputDevices();
+    List<HdmiDeviceInfo> getInputDevices();
     void sendVendorCommand(int deviceType, int targetAddress, in byte[] params,
             boolean hasVendorId);
     void addVendorCommandListener(IHdmiVendorCommandListener listener, int deviceType);
diff --git a/core/java/android/hardware/hdmi/IHdmiDeviceEventListener.aidl b/core/java/android/hardware/hdmi/IHdmiDeviceEventListener.aidl
index c4e5989..94fd14f 100644
--- a/core/java/android/hardware/hdmi/IHdmiDeviceEventListener.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiDeviceEventListener.aidl
@@ -16,7 +16,7 @@
 
 package android.hardware.hdmi;
 
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 
 /**
  * Callback interface definition for HDMI client to get informed of
@@ -27,9 +27,9 @@
 oneway interface IHdmiDeviceEventListener {
 
     /**
-     * @param deviceInfo {@link HdmiCecDeviceInfo} of the logical device whose
+     * @param deviceInfo {@link HdmiDeviceInfo} of the logical device whose
      *                   status has changed
      * @param activated true if the device gets activated
      */
-    void onStatusChanged(in HdmiCecDeviceInfo deviceInfo, in boolean activated);
+    void onStatusChanged(in HdmiDeviceInfo deviceInfo, in boolean activated);
 }
diff --git a/core/java/android/hardware/hdmi/IHdmiInputChangeListener.aidl b/core/java/android/hardware/hdmi/IHdmiInputChangeListener.aidl
index 98ad300..46a20c7 100644
--- a/core/java/android/hardware/hdmi/IHdmiInputChangeListener.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiInputChangeListener.aidl
@@ -16,7 +16,7 @@
 
 package android.hardware.hdmi;
 
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 
 /**
  * Callback interface definition for TV to get informed of
@@ -25,5 +25,5 @@
  * @hide
  */
 oneway interface IHdmiInputChangeListener {
-    void onChanged(in HdmiCecDeviceInfo device);
+    void onChanged(in HdmiDeviceInfo device);
 }
diff --git a/core/java/android/hardware/hdmi/IHdmiRecordListener.aidl b/core/java/android/hardware/hdmi/IHdmiRecordListener.aidl
index fba4b05..44d9065 100644
--- a/core/java/android/hardware/hdmi/IHdmiRecordListener.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiRecordListener.aidl
@@ -36,7 +36,14 @@
      void onOneTouchRecordResult(int result);
      /**
       * Called when timer recording is started or failed during initialization.
+
       * @param result result code for timer recording
       */
      void onTimerRecordingResult(int result);
+     /**
+      * Called when receiving result for clear timer recording request.
+      *
+      * @param result result of clear timer.
+      */
+     void onClearTimerRecordingResult(int result);
  }
\ No newline at end of file
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java
index 4498789..7a49eb5 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.java
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java
@@ -16,6 +16,7 @@
 
 package android.hardware.soundtrigger;
 
+import android.media.AudioFormat;
 import android.os.Handler;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -86,11 +87,15 @@
         /** Rated power consumption when detection is active with TDB silence/sound/speech ratio */
         public final int powerConsumptionMw;
 
+        /** Returns the trigger (key phrase) capture in the binary data of the
+         * recognition callback event */
+        public final boolean returnsTriggerInEvent;
+
         ModuleProperties(int id, String implementor, String description,
                 String uuid, int version, int maxSoundModels, int maxKeyphrases,
                 int maxUsers, int recognitionModes, boolean supportsCaptureTransition,
                 int maxBufferMs, boolean supportsConcurrentCapture,
-                int powerConsumptionMw) {
+                int powerConsumptionMw, boolean returnsTriggerInEvent) {
             this.id = id;
             this.implementor = implementor;
             this.description = description;
@@ -104,6 +109,7 @@
             this.maxBufferMs = maxBufferMs;
             this.supportsConcurrentCapture = supportsConcurrentCapture;
             this.powerConsumptionMw = powerConsumptionMw;
+            this.returnsTriggerInEvent = returnsTriggerInEvent;
         }
 
         public static final Parcelable.Creator<ModuleProperties> CREATOR
@@ -131,10 +137,11 @@
             int maxBufferMs = in.readInt();
             boolean supportsConcurrentCapture = in.readByte() == 1;
             int powerConsumptionMw = in.readInt();
+            boolean returnsTriggerInEvent = in.readByte() == 1;
             return new ModuleProperties(id, implementor, description, uuid, version,
                     maxSoundModels, maxKeyphrases, maxUsers, recognitionModes,
                     supportsCaptureTransition, maxBufferMs, supportsConcurrentCapture,
-                    powerConsumptionMw);
+                    powerConsumptionMw, returnsTriggerInEvent);
         }
 
         @Override
@@ -152,6 +159,7 @@
             dest.writeInt(maxBufferMs);
             dest.writeByte((byte) (supportsConcurrentCapture ? 1 : 0));
             dest.writeInt(powerConsumptionMw);
+            dest.writeByte((byte) (returnsTriggerInEvent ? 1 : 0));
         }
 
         @Override
@@ -167,7 +175,8 @@
                     + maxUsers + ", recognitionModes=" + recognitionModes
                     + ", supportsCaptureTransition=" + supportsCaptureTransition + ", maxBufferMs="
                     + maxBufferMs + ", supportsConcurrentCapture=" + supportsConcurrentCapture
-                    + ", powerConsumptionMw=" + powerConsumptionMw + "]";
+                    + ", powerConsumptionMw=" + powerConsumptionMw
+                    + ", returnsTriggerInEvent=" + returnsTriggerInEvent + "]";
         }
     }
 
@@ -190,11 +199,15 @@
         /** Sound model type (e.g. TYPE_KEYPHRASE); */
         public final int type;
 
+        /** Unique sound model vendor identifier */
+        public final UUID vendorUuid;
+
         /** Opaque data. For use by vendor implementation and enrollment application */
         public final byte[] data;
 
-        public SoundModel(UUID uuid, int type, byte[] data) {
+        public SoundModel(UUID uuid, UUID vendorUuid, int type, byte[] data) {
             this.uuid = uuid;
+            this.vendorUuid = vendorUuid;
             this.type = type;
             this.data = data;
         }
@@ -329,8 +342,9 @@
         /** Key phrases in this sound model */
         public final Keyphrase[] keyphrases; // keyword phrases in model
 
-        public KeyphraseSoundModel(UUID id, byte[] data, Keyphrase[] keyphrases) {
-            super(id, TYPE_KEYPHRASE, data);
+        public KeyphraseSoundModel(
+                UUID uuid, UUID vendorUuid, byte[] data, Keyphrase[] keyphrases) {
+            super(uuid, vendorUuid, TYPE_KEYPHRASE, data);
             this.keyphrases = keyphrases;
         }
 
@@ -347,9 +361,14 @@
 
         private static KeyphraseSoundModel fromParcel(Parcel in) {
             UUID uuid = UUID.fromString(in.readString());
+            UUID vendorUuid = null;
+            int length = in.readInt();
+            if (length >= 0) {
+                vendorUuid = UUID.fromString(in.readString());
+            }
             byte[] data = in.readBlob();
             Keyphrase[] keyphrases = in.createTypedArray(Keyphrase.CREATOR);
-            return new KeyphraseSoundModel(uuid, data, keyphrases);
+            return new KeyphraseSoundModel(uuid, vendorUuid, data, keyphrases);
         }
 
         @Override
@@ -360,14 +379,21 @@
         @Override
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeString(uuid.toString());
+            if (vendorUuid == null) {
+                dest.writeInt(-1);
+            } else {
+                dest.writeInt(vendorUuid.toString().length());
+                dest.writeString(vendorUuid.toString());
+            }
             dest.writeBlob(data);
             dest.writeTypedArray(keyphrases, flags);
         }
 
         @Override
         public String toString() {
-            return "KeyphraseSoundModel [keyphrases=" + Arrays.toString(keyphrases) + ", uuid="
-                    + uuid + ", type=" + type + ", data=" + (data == null ? 0 : data.length) + "]";
+            return "KeyphraseSoundModel [keyphrases=" + Arrays.toString(keyphrases)
+                    + ", uuid=" + uuid + ", vendorUuid=" + vendorUuid
+                    + ", type=" + type + ", data=" + (data == null ? 0 : data.length) + "]";
         }
     }
 
@@ -411,18 +437,26 @@
         public final int captureDelayMs;
         /** Duration in ms of audio captured before the start of the trigger. 0 if none. */
         public final int capturePreambleMs;
+        /** True if  the trigger (key phrase capture is present in binary data */
+        public final boolean triggerInData;
+        /** Audio format of either the trigger in event data or to use for capture of the
+          * rest of the utterance */
+        public AudioFormat captureFormat;
         /** Opaque data for use by system applications who know about voice engine internals,
          * typically during enrollment. */
         public final byte[] data;
 
         public RecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
-                int captureSession, int captureDelayMs, int capturePreambleMs, byte[] data) {
+                int captureSession, int captureDelayMs, int capturePreambleMs,
+                boolean triggerInData, AudioFormat captureFormat, byte[] data) {
             this.status = status;
             this.soundModelHandle = soundModelHandle;
             this.captureAvailable = captureAvailable;
             this.captureSession = captureSession;
             this.captureDelayMs = captureDelayMs;
             this.capturePreambleMs = capturePreambleMs;
+            this.triggerInData = triggerInData;
+            this.captureFormat = captureFormat;
             this.data = data;
         }
 
@@ -444,9 +478,21 @@
             int captureSession = in.readInt();
             int captureDelayMs = in.readInt();
             int capturePreambleMs = in.readInt();
+            boolean triggerInData = in.readByte() == 1;
+            AudioFormat captureFormat = null;
+            if (triggerInData) {
+                int sampleRate = in.readInt();
+                int encoding = in.readInt();
+                int channelMask = in.readInt();
+                captureFormat = (new AudioFormat.Builder())
+                        .setChannelMask(channelMask)
+                        .setEncoding(encoding)
+                        .setSampleRate(sampleRate)
+                        .build();
+            }
             byte[] data = in.readBlob();
             return new RecognitionEvent(status, soundModelHandle, captureAvailable, captureSession,
-                    captureDelayMs, capturePreambleMs, data);
+                    captureDelayMs, capturePreambleMs, triggerInData, captureFormat, data);
         }
 
         @Override
@@ -462,6 +508,14 @@
             dest.writeInt(captureSession);
             dest.writeInt(captureDelayMs);
             dest.writeInt(capturePreambleMs);
+            if (triggerInData && (captureFormat != null)) {
+                dest.writeByte((byte)1);
+                dest.writeInt(captureFormat.getSampleRate());
+                dest.writeInt(captureFormat.getEncoding());
+                dest.writeInt(captureFormat.getChannelMask());
+            } else {
+                dest.writeByte((byte)0);
+            }
             dest.writeBlob(data);
         }
 
@@ -473,6 +527,12 @@
             result = prime * result + captureDelayMs;
             result = prime * result + capturePreambleMs;
             result = prime * result + captureSession;
+            result = prime * result + (triggerInData ? 1231 : 1237);
+            if (captureFormat != null) {
+                result = prime * result + captureFormat.getSampleRate();
+                result = prime * result + captureFormat.getEncoding();
+                result = prime * result + captureFormat.getChannelMask();
+            }
             result = prime * result + Arrays.hashCode(data);
             result = prime * result + soundModelHandle;
             result = prime * result + status;
@@ -502,6 +562,14 @@
                 return false;
             if (status != other.status)
                 return false;
+            if (triggerInData != other.triggerInData)
+                return false;
+            if (captureFormat.getSampleRate() != other.captureFormat.getSampleRate())
+                return false;
+            if (captureFormat.getEncoding() != other.captureFormat.getEncoding())
+                return false;
+            if (captureFormat.getChannelMask() != other.captureFormat.getChannelMask())
+                return false;
             return true;
         }
 
@@ -511,6 +579,13 @@
                     + ", captureAvailable=" + captureAvailable + ", captureSession="
                     + captureSession + ", captureDelayMs=" + captureDelayMs
                     + ", capturePreambleMs=" + capturePreambleMs
+                    + ", triggerInData=" + triggerInData
+                    + ((captureFormat == null) ? "" :
+                        (", sampleRate=" + captureFormat.getSampleRate()))
+                    + ((captureFormat == null) ? "" :
+                        (", encoding=" + captureFormat.getEncoding()))
+                    + ((captureFormat == null) ? "" :
+                        (", channelMask=" + captureFormat.getChannelMask()))
                     + ", data=" + (data == null ? 0 : data.length) + "]";
         }
     }
@@ -524,6 +599,11 @@
         /** True if the DSP should capture the trigger sound and make it available for further
          * capture. */
         public final boolean captureRequested;
+        /**
+         * True if the service should restart listening after the DSP triggers.
+         * Note: This config flag is currently used at the service layer rather than by the DSP.
+         */
+        public final boolean allowMultipleTriggers;
         /** List of all keyphrases in the sound model for which recognition should be performed with
          * options for each keyphrase. */
         public final KeyphraseRecognitionExtra keyphrases[];
@@ -531,9 +611,10 @@
          * typically during enrollment. */
         public final byte[] data;
 
-        public RecognitionConfig(boolean captureRequested,
+        public RecognitionConfig(boolean captureRequested, boolean allowMultipleTriggers,
                 KeyphraseRecognitionExtra keyphrases[], byte[] data) {
             this.captureRequested = captureRequested;
+            this.allowMultipleTriggers = allowMultipleTriggers;
             this.keyphrases = keyphrases;
             this.data = data;
         }
@@ -551,15 +632,17 @@
 
         private static RecognitionConfig fromParcel(Parcel in) {
             boolean captureRequested = in.readByte() == 1;
+            boolean allowMultipleTriggers = in.readByte() == 1;
             KeyphraseRecognitionExtra[] keyphrases =
                     in.createTypedArray(KeyphraseRecognitionExtra.CREATOR);
             byte[] data = in.readBlob();
-            return new RecognitionConfig(captureRequested, keyphrases, data);
+            return new RecognitionConfig(captureRequested, allowMultipleTriggers, keyphrases, data);
         }
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeByte((byte) (captureRequested ? 1 : 0));
+            dest.writeByte((byte) (allowMultipleTriggers ? 1 : 0));
             dest.writeTypedArray(keyphrases, flags);
             dest.writeBlob(data);
         }
@@ -571,9 +654,9 @@
 
         @Override
         public String toString() {
-            return "RecognitionConfig [captureRequested=" + captureRequested + ", keyphrases="
-                    + Arrays.toString(keyphrases)
-                    + ", data=" + (data == null ? 0 : data.length) + "]";
+            return "RecognitionConfig [captureRequested=" + captureRequested
+                    + ", allowMultipleTriggers=" + allowMultipleTriggers + ", keyphrases="
+                    + Arrays.toString(keyphrases) + ", data=" + Arrays.toString(data) + "]";
         }
     }
 
@@ -665,14 +748,19 @@
         /** Recognition modes matched for this event */
         public final int recognitionModes;
 
+        /** Confidence level for mode RECOGNITION_MODE_VOICE_TRIGGER when user identification
+         * is not performed */
+        public final int coarseConfidenceLevel;
+
         /** Confidence levels for all users recognized (KeyphraseRecognitionEvent) or to
          * be recognized (RecognitionConfig) */
         public final ConfidenceLevel[] confidenceLevels;
 
-        public KeyphraseRecognitionExtra(int id, int recognitionModes,
-                                  ConfidenceLevel[] confidenceLevels) {
+        public KeyphraseRecognitionExtra(int id, int recognitionModes, int coarseConfidenceLevel,
+                ConfidenceLevel[] confidenceLevels) {
             this.id = id;
             this.recognitionModes = recognitionModes;
+            this.coarseConfidenceLevel = coarseConfidenceLevel;
             this.confidenceLevels = confidenceLevels;
         }
 
@@ -690,14 +778,17 @@
         private static KeyphraseRecognitionExtra fromParcel(Parcel in) {
             int id = in.readInt();
             int recognitionModes = in.readInt();
+            int coarseConfidenceLevel = in.readInt();
             ConfidenceLevel[] confidenceLevels = in.createTypedArray(ConfidenceLevel.CREATOR);
-            return new KeyphraseRecognitionExtra(id, recognitionModes, confidenceLevels);
+            return new KeyphraseRecognitionExtra(id, recognitionModes, coarseConfidenceLevel,
+                    confidenceLevels);
         }
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeInt(id);
             dest.writeInt(recognitionModes);
+            dest.writeInt(coarseConfidenceLevel);
             dest.writeTypedArray(confidenceLevels, flags);
         }
 
@@ -713,6 +804,7 @@
             result = prime * result + Arrays.hashCode(confidenceLevels);
             result = prime * result + id;
             result = prime * result + recognitionModes;
+            result = prime * result + coarseConfidenceLevel;
             return result;
         }
 
@@ -731,12 +823,15 @@
                 return false;
             if (recognitionModes != other.recognitionModes)
                 return false;
+            if (coarseConfidenceLevel != other.coarseConfidenceLevel)
+                return false;
             return true;
         }
 
         @Override
         public String toString() {
             return "KeyphraseRecognitionExtra [id=" + id + ", recognitionModes=" + recognitionModes
+                    + ", coarseConfidenceLevel=" + coarseConfidenceLevel
                     + ", confidenceLevels=" + Arrays.toString(confidenceLevels) + "]";
         }
     }
@@ -748,15 +843,12 @@
         /** Indicates if the key phrase is present in the buffered audio available for capture */
         public final KeyphraseRecognitionExtra[] keyphraseExtras;
 
-        /** Additional data available for each recognized key phrases in the model */
-        public final boolean keyphraseInCapture;
-
         public KeyphraseRecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
-               int captureSession, int captureDelayMs, int capturePreambleMs, byte[] data,
-               boolean keyphraseInCapture, KeyphraseRecognitionExtra[] keyphraseExtras) {
+               int captureSession, int captureDelayMs, int capturePreambleMs,
+               boolean triggerInData, AudioFormat captureFormat, byte[] data,
+               KeyphraseRecognitionExtra[] keyphraseExtras) {
             super(status, soundModelHandle, captureAvailable, captureSession, captureDelayMs,
-                  capturePreambleMs, data);
-            this.keyphraseInCapture = keyphraseInCapture;
+                  capturePreambleMs, triggerInData, captureFormat, data);
             this.keyphraseExtras = keyphraseExtras;
         }
 
@@ -778,13 +870,24 @@
             int captureSession = in.readInt();
             int captureDelayMs = in.readInt();
             int capturePreambleMs = in.readInt();
+            boolean triggerInData = in.readByte() == 1;
+            AudioFormat captureFormat = null;
+            if (triggerInData) {
+                int sampleRate = in.readInt();
+                int encoding = in.readInt();
+                int channelMask = in.readInt();
+                captureFormat = (new AudioFormat.Builder())
+                        .setChannelMask(channelMask)
+                        .setEncoding(encoding)
+                        .setSampleRate(sampleRate)
+                        .build();
+            }
             byte[] data = in.readBlob();
-            boolean keyphraseInCapture = in.readByte() == 1;
             KeyphraseRecognitionExtra[] keyphraseExtras =
                     in.createTypedArray(KeyphraseRecognitionExtra.CREATOR);
             return new KeyphraseRecognitionEvent(status, soundModelHandle, captureAvailable,
-                    captureSession, captureDelayMs, capturePreambleMs, data, keyphraseInCapture,
-                    keyphraseExtras);
+                    captureSession, captureDelayMs, capturePreambleMs, triggerInData,
+                    captureFormat, data, keyphraseExtras);
         }
 
         @Override
@@ -795,8 +898,15 @@
             dest.writeInt(captureSession);
             dest.writeInt(captureDelayMs);
             dest.writeInt(capturePreambleMs);
+            if (triggerInData && (captureFormat != null)) {
+                dest.writeByte((byte)1);
+                dest.writeInt(captureFormat.getSampleRate());
+                dest.writeInt(captureFormat.getEncoding());
+                dest.writeInt(captureFormat.getChannelMask());
+            } else {
+                dest.writeByte((byte)0);
+            }
             dest.writeBlob(data);
-            dest.writeByte((byte) (keyphraseInCapture ? 1 : 0));
             dest.writeTypedArray(keyphraseExtras, flags);
         }
 
@@ -810,7 +920,6 @@
             final int prime = 31;
             int result = super.hashCode();
             result = prime * result + Arrays.hashCode(keyphraseExtras);
-            result = prime * result + (keyphraseInCapture ? 1231 : 1237);
             return result;
         }
 
@@ -825,23 +934,127 @@
             KeyphraseRecognitionEvent other = (KeyphraseRecognitionEvent) obj;
             if (!Arrays.equals(keyphraseExtras, other.keyphraseExtras))
                 return false;
-            if (keyphraseInCapture != other.keyphraseInCapture)
-                return false;
             return true;
         }
 
         @Override
         public String toString() {
             return "KeyphraseRecognitionEvent [keyphraseExtras=" + Arrays.toString(keyphraseExtras)
-                    + ", keyphraseInCapture=" + keyphraseInCapture + ", status=" + status
+                    + ", status=" + status
                     + ", soundModelHandle=" + soundModelHandle + ", captureAvailable="
                     + captureAvailable + ", captureSession=" + captureSession + ", captureDelayMs="
                     + captureDelayMs + ", capturePreambleMs=" + capturePreambleMs
+                    + ", triggerInData=" + triggerInData
+                    + ((captureFormat == null) ? "" :
+                        (", sampleRate=" + captureFormat.getSampleRate()))
+                    + ((captureFormat == null) ? "" :
+                        (", encoding=" + captureFormat.getEncoding()))
+                    + ((captureFormat == null) ? "" :
+                        (", channelMask=" + captureFormat.getChannelMask()))
                     + ", data=" + (data == null ? 0 : data.length) + "]";
         }
     }
 
     /**
+     *  Status codes for {@link SoundModelEvent}
+     */
+    /** Sound Model was updated */
+    public static final int SOUNDMODEL_STATUS_UPDATED = 0;
+
+    /**
+     *  A SoundModelEvent is provided by the
+     *  {@link StatusListener#onSoundModelUpdate(SoundModelEvent)}
+     *  callback when a sound model has been updated by the implementation
+     */
+    public static class SoundModelEvent implements Parcelable {
+        /** Status e.g {@link #SOUNDMODEL_STATUS_UPDATED} */
+        public final int status;
+        /** The updated sound model handle */
+        public final int soundModelHandle;
+        /** New sound model data */
+        public final byte[] data;
+
+        SoundModelEvent(int status, int soundModelHandle, byte[] data) {
+            this.status = status;
+            this.soundModelHandle = soundModelHandle;
+            this.data = data;
+        }
+
+        public static final Parcelable.Creator<SoundModelEvent> CREATOR
+                = new Parcelable.Creator<SoundModelEvent>() {
+            public SoundModelEvent createFromParcel(Parcel in) {
+                return SoundModelEvent.fromParcel(in);
+            }
+
+            public SoundModelEvent[] newArray(int size) {
+                return new SoundModelEvent[size];
+            }
+        };
+
+        private static SoundModelEvent fromParcel(Parcel in) {
+            int status = in.readInt();
+            int soundModelHandle = in.readInt();
+            byte[] data = in.readBlob();
+            return new SoundModelEvent(status, soundModelHandle, data);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(status);
+            dest.writeInt(soundModelHandle);
+            dest.writeBlob(data);
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + Arrays.hashCode(data);
+            result = prime * result + soundModelHandle;
+            result = prime * result + status;
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            SoundModelEvent other = (SoundModelEvent) obj;
+            if (!Arrays.equals(data, other.data))
+                return false;
+            if (soundModelHandle != other.soundModelHandle)
+                return false;
+            if (status != other.status)
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString() {
+            return "SoundModelEvent [status=" + status + ", soundModelHandle=" + soundModelHandle
+                    + ", data=" + (data == null ? 0 : data.length) + "]";
+        }
+    }
+
+    /**
+     *  Native service state. {@link StatusListener#onServiceStateChange(int)}
+     */
+    // Keep in sync with system/core/include/system/sound_trigger.h
+    /** Sound trigger service is enabled */
+    public static final int SERVICE_STATE_ENABLED = 0;
+    /** Sound trigger service is disabled */
+    public static final int SERVICE_STATE_DISABLED = 1;
+
+    /**
      * Returns a list of descriptors for all harware modules loaded.
      * @param modules A ModuleProperties array where the list will be returned.
      * @return - {@link #STATUS_OK} in case of success
@@ -883,6 +1096,18 @@
         public abstract void onRecognition(RecognitionEvent event);
 
         /**
+         * Called when a sound model has been updated
+         */
+        public abstract void onSoundModelUpdate(SoundModelEvent event);
+
+        /**
+         * Called when the sound trigger native service state changes.
+         * @param state Native service state. One of {@link SoundTrigger#SERVICE_STATE_ENABLED},
+         * {@link SoundTrigger#SERVICE_STATE_DISABLED}
+         */
+        public abstract void onServiceStateChange(int state);
+
+        /**
          * Called when the sound trigger native service dies
          */
         public abstract void onServiceDied();
diff --git a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
index 4a54fd8..1a8723d 100644
--- a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
+++ b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
@@ -36,8 +36,11 @@
     private int mId;
     private NativeEventHandlerDelegate mEventHandlerDelegate;
 
+    // to be kept in sync with core/jni/android_hardware_SoundTrigger.cpp
     private static final int EVENT_RECOGNITION = 1;
     private static final int EVENT_SERVICE_DIED = 2;
+    private static final int EVENT_SOUNDMODEL = 3;
+    private static final int EVENT_SERVICE_STATE_CHANGE = 4;
 
     SoundTriggerModule(int moduleId, SoundTrigger.StatusListener listener, Handler handler) {
         mId = moduleId;
@@ -133,10 +136,7 @@
             if (handler != null) {
                 looper = handler.getLooper();
             } else {
-                looper = Looper.myLooper();
-                if (looper == null) {
-                    looper = Looper.getMainLooper();
-                }
+                looper = Looper.getMainLooper();
             }
 
             // construct the event handler with this looper
@@ -152,6 +152,17 @@
                                         (SoundTrigger.RecognitionEvent)msg.obj);
                             }
                             break;
+                        case EVENT_SOUNDMODEL:
+                            if (listener != null) {
+                                listener.onSoundModelUpdate(
+                                        (SoundTrigger.SoundModelEvent)msg.obj);
+                            }
+                            break;
+                        case EVENT_SERVICE_STATE_CHANGE:
+                            if (listener != null) {
+                                listener.onServiceStateChange(msg.arg1);
+                            }
+                            break;
                         case EVENT_SERVICE_DIED:
                             if (listener != null) {
                                 listener.onServiceDied();
diff --git a/core/java/android/net/CaptivePortalTracker.java b/core/java/android/net/CaptivePortalTracker.java
deleted file mode 100644
index 89c17c7..0000000
--- a/core/java/android/net/CaptivePortalTracker.java
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.net.ConnectivityManager;
-import android.net.IConnectivityManager;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.Handler;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.telephony.CellIdentityCdma;
-import android.telephony.CellIdentityGsm;
-import android.telephony.CellIdentityLte;
-import android.telephony.CellIdentityWcdma;
-import android.telephony.CellInfo;
-import android.telephony.CellInfoCdma;
-import android.telephony.CellInfoGsm;
-import android.telephony.CellInfoLte;
-import android.telephony.CellInfoWcdma;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.List;
-
-/**
- * This class allows captive portal detection on a network.
- * @hide
- */
-public class CaptivePortalTracker extends StateMachine {
-    private static final boolean DBG = true;
-    private static final String TAG = "CaptivePortalTracker";
-
-    private static final String DEFAULT_SERVER = "clients3.google.com";
-
-    private static final int SOCKET_TIMEOUT_MS = 10000;
-
-    public static final String ACTION_NETWORK_CONDITIONS_MEASURED =
-            "android.net.conn.NETWORK_CONDITIONS_MEASURED";
-    public static final String EXTRA_CONNECTIVITY_TYPE = "extra_connectivity_type";
-    public static final String EXTRA_NETWORK_TYPE = "extra_network_type";
-    public static final String EXTRA_RESPONSE_RECEIVED = "extra_response_received";
-    public static final String EXTRA_IS_CAPTIVE_PORTAL = "extra_is_captive_portal";
-    public static final String EXTRA_CELL_ID = "extra_cellid";
-    public static final String EXTRA_SSID = "extra_ssid";
-    public static final String EXTRA_BSSID = "extra_bssid";
-    /** real time since boot */
-    public static final String EXTRA_REQUEST_TIMESTAMP_MS = "extra_request_timestamp_ms";
-    public static final String EXTRA_RESPONSE_TIMESTAMP_MS = "extra_response_timestamp_ms";
-
-    private static final String PERMISSION_ACCESS_NETWORK_CONDITIONS =
-            "android.permission.ACCESS_NETWORK_CONDITIONS";
-
-    private String mServer;
-    private String mUrl;
-    private boolean mIsCaptivePortalCheckEnabled = false;
-    private final IConnectivityManager mConnService;
-    private final TelephonyManager mTelephonyManager;
-    private final WifiManager mWifiManager;
-    private final Context mContext;
-    private NetworkInfo mNetworkInfo;
-
-    private static final int CMD_CONNECTIVITY_CHANGE    = 1;
-    private static final int CMD_DELAYED_CAPTIVE_CHECK  = 2;
-
-    /* This delay happens every time before we do a captive check on a network */
-    private static final int DELAYED_CHECK_INTERVAL_MS = 10000;
-    private int mDelayedCheckToken = 0;
-
-    private final State mDefaultState = new DefaultState();
-    private final State mNoActiveNetworkState = new NoActiveNetworkState();
-    private final State mActiveNetworkState = new ActiveNetworkState();
-    private final State mDelayedCaptiveCheckState = new DelayedCaptiveCheckState();
-
-    private static final String SETUP_WIZARD_PACKAGE = "com.google.android.setupwizard";
-    private boolean mDeviceProvisioned = false;
-    @SuppressWarnings("unused")
-    private final ProvisioningObserver mProvisioningObserver;
-
-    private CaptivePortalTracker(Context context, IConnectivityManager cs) {
-        super(TAG);
-
-        mContext = context;
-        mConnService = cs;
-        mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
-        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
-        mProvisioningObserver = new ProvisioningObserver();
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
-        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE);
-        mContext.registerReceiver(mReceiver, filter);
-
-        mServer = Settings.Global.getString(mContext.getContentResolver(),
-                Settings.Global.CAPTIVE_PORTAL_SERVER);
-        if (mServer == null) mServer = DEFAULT_SERVER;
-
-        mIsCaptivePortalCheckEnabled = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED, 1) == 1;
-
-        addState(mDefaultState);
-            addState(mNoActiveNetworkState, mDefaultState);
-            addState(mActiveNetworkState, mDefaultState);
-                addState(mDelayedCaptiveCheckState, mActiveNetworkState);
-        setInitialState(mNoActiveNetworkState);
-    }
-
-    private class ProvisioningObserver extends ContentObserver {
-        ProvisioningObserver() {
-            super(new Handler());
-            mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
-                    Settings.Global.DEVICE_PROVISIONED), false, this);
-            onChange(false); // load initial value
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            mDeviceProvisioned = Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.DEVICE_PROVISIONED, 0) != 0;
-        }
-    }
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            // Normally, we respond to CONNECTIVITY_ACTION, allowing time for the change in
-            // connectivity to stabilize, but if the device is not yet provisioned, respond
-            // immediately to speed up transit through the setup wizard.
-            if ((mDeviceProvisioned && action.equals(ConnectivityManager.CONNECTIVITY_ACTION))
-                    || (!mDeviceProvisioned
-                            && action.equals(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE))) {
-                NetworkInfo info = intent.getParcelableExtra(
-                        ConnectivityManager.EXTRA_NETWORK_INFO);
-                sendMessage(obtainMessage(CMD_CONNECTIVITY_CHANGE, info));
-            }
-        }
-    };
-
-    public static CaptivePortalTracker makeCaptivePortalTracker(Context context,
-            IConnectivityManager cs) {
-        CaptivePortalTracker captivePortal = new CaptivePortalTracker(context, cs);
-        captivePortal.start();
-        return captivePortal;
-    }
-
-    private class DefaultState extends State {
-
-        @Override
-        public boolean processMessage(Message message) {
-            loge("Ignoring " + message);
-            return HANDLED;
-        }
-    }
-
-    private class NoActiveNetworkState extends State {
-        @Override
-        public void enter() {
-            setNotificationOff();
-            mNetworkInfo = null;
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) log(getName() + message.toString());
-            InetAddress server;
-            NetworkInfo info;
-            switch (message.what) {
-                case CMD_CONNECTIVITY_CHANGE:
-                    info = (NetworkInfo) message.obj;
-                    if (info.getType() == ConnectivityManager.TYPE_WIFI) {
-                        if (info.isConnected() && isActiveNetwork(info)) {
-                            mNetworkInfo = info;
-                            transitionTo(mDelayedCaptiveCheckState);
-                        }
-                    } else {
-                        log(getName() + " not a wifi connectivity change, ignore");
-                    }
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    private class ActiveNetworkState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            NetworkInfo info;
-            switch (message.what) {
-               case CMD_CONNECTIVITY_CHANGE:
-                    info = (NetworkInfo) message.obj;
-                    if (!info.isConnected()
-                            && info.getType() == mNetworkInfo.getType()) {
-                        if (DBG) log("Disconnected from active network " + info);
-                        transitionTo(mNoActiveNetworkState);
-                    } else if (info.getType() != mNetworkInfo.getType() &&
-                            info.isConnected() &&
-                            isActiveNetwork(info)) {
-                        if (DBG) log("Active network switched " + info);
-                        deferMessage(message);
-                        transitionTo(mNoActiveNetworkState);
-                    }
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-
-
-    private class DelayedCaptiveCheckState extends State {
-        @Override
-        public void enter() {
-            Message message = obtainMessage(CMD_DELAYED_CAPTIVE_CHECK, ++mDelayedCheckToken, 0);
-            if (mDeviceProvisioned) {
-                sendMessageDelayed(message, DELAYED_CHECK_INTERVAL_MS);
-            } else {
-                sendMessage(message);
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) log(getName() + message.toString());
-            switch (message.what) {
-                case CMD_DELAYED_CAPTIVE_CHECK:
-                    setNotificationOff();
-
-                    if (message.arg1 == mDelayedCheckToken) {
-                        InetAddress server = lookupHost(mServer);
-                        boolean captive = server != null && isCaptivePortal(server);
-                        if (captive) {
-                            if (DBG) log("Captive network " + mNetworkInfo);
-                        } else {
-                            if (DBG) log("Not captive network " + mNetworkInfo);
-                        }
-                        notifyPortalCheckCompleted(mNetworkInfo, captive);
-                        if (mDeviceProvisioned) {
-                            if (captive) {
-                                // Setup Wizard will assist the user in connecting to a captive
-                                // portal, so make the notification visible unless during setup
-                                try {
-                                    mConnService.setProvisioningNotificationVisible(true,
-                                        mNetworkInfo.getType(), mNetworkInfo.getExtraInfo(), mUrl);
-                                } catch(RemoteException e) {
-                                    e.printStackTrace();
-                                }
-                            }
-                        } else {
-                            Intent intent = new Intent(
-                                    ConnectivityManager.ACTION_CAPTIVE_PORTAL_TEST_COMPLETED);
-                            intent.putExtra(ConnectivityManager.EXTRA_IS_CAPTIVE_PORTAL, captive);
-                            intent.setPackage(SETUP_WIZARD_PACKAGE);
-                            mContext.sendBroadcast(intent);
-                        }
-
-                        transitionTo(mActiveNetworkState);
-                    }
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    private void notifyPortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
-        if (info == null) {
-            loge("notifyPortalCheckComplete on null");
-            return;
-        }
-        try {
-            if (DBG) log("notifyPortalCheckCompleted: captive=" + isCaptivePortal + " ni=" + info);
-            mConnService.captivePortalCheckCompleted(info, isCaptivePortal);
-        } catch(RemoteException e) {
-            e.printStackTrace();
-        }
-    }
-
-    private boolean isActiveNetwork(NetworkInfo info) {
-        try {
-            NetworkInfo active = mConnService.getActiveNetworkInfo();
-            if (active != null && active.getType() == info.getType()) {
-                return true;
-            }
-        } catch (RemoteException e) {
-            e.printStackTrace();
-        }
-        return false;
-    }
-
-    private void setNotificationOff() {
-        try {
-            if (mNetworkInfo != null) {
-                mConnService.setProvisioningNotificationVisible(false, mNetworkInfo.getType(),
-                    null, null);
-            }
-        } catch (RemoteException e) {
-            log("setNotificationOff: " + e);
-        }
-    }
-
-    /**
-     * Do a URL fetch on a known server to see if we get the data we expect.
-     * Measure the response time and broadcast that.
-     */
-    private boolean isCaptivePortal(InetAddress server) {
-        HttpURLConnection urlConnection = null;
-        if (!mIsCaptivePortalCheckEnabled) return false;
-
-        mUrl = "http://" + server.getHostAddress() + "/generate_204";
-        if (DBG) log("Checking " + mUrl);
-        long requestTimestamp = -1;
-        try {
-            URL url = new URL(mUrl);
-            urlConnection = (HttpURLConnection) url.openConnection();
-            urlConnection.setInstanceFollowRedirects(false);
-            urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
-            urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
-            urlConnection.setUseCaches(false);
-
-            // Time how long it takes to get a response to our request
-            requestTimestamp = SystemClock.elapsedRealtime();
-
-            urlConnection.getInputStream();
-
-            // Time how long it takes to get a response to our request
-            long responseTimestamp = SystemClock.elapsedRealtime();
-
-            // we got a valid response, but not from the real google
-            int rspCode = urlConnection.getResponseCode();
-            boolean isCaptivePortal = rspCode != 204;
-
-            sendNetworkConditionsBroadcast(true /* response received */, isCaptivePortal,
-                    requestTimestamp, responseTimestamp);
-
-            if (DBG) log("isCaptivePortal: ret=" + isCaptivePortal + " rspCode=" + rspCode);
-            return isCaptivePortal;
-        } catch (IOException e) {
-            if (DBG) log("Probably not a portal: exception " + e);
-            if (requestTimestamp != -1) {
-                sendFailedCaptivePortalCheckBroadcast(requestTimestamp);
-            } // else something went wrong with setting up the urlConnection
-            return false;
-        } finally {
-            if (urlConnection != null) {
-                urlConnection.disconnect();
-            }
-        }
-    }
-
-    private InetAddress lookupHost(String hostname) {
-        InetAddress inetAddress[];
-        try {
-            inetAddress = InetAddress.getAllByName(hostname);
-        } catch (UnknownHostException e) {
-            sendFailedCaptivePortalCheckBroadcast(SystemClock.elapsedRealtime());
-            return null;
-        }
-
-        for (InetAddress a : inetAddress) {
-            if (a instanceof Inet4Address) return a;
-        }
-
-        sendFailedCaptivePortalCheckBroadcast(SystemClock.elapsedRealtime());
-        return null;
-    }
-
-    private void sendFailedCaptivePortalCheckBroadcast(long requestTimestampMs) {
-        sendNetworkConditionsBroadcast(false /* response received */, false /* ignored */,
-                requestTimestampMs, 0 /* ignored */);
-    }
-
-    /**
-     * @param responseReceived - whether or not we received a valid HTTP response to our request.
-     * If false, isCaptivePortal and responseTimestampMs are ignored
-     */
-    private void sendNetworkConditionsBroadcast(boolean responseReceived, boolean isCaptivePortal,
-            long requestTimestampMs, long responseTimestampMs) {
-        if (Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 0) {
-            if (DBG) log("Don't send network conditions - lacking user consent.");
-            return;
-        }
-
-        Intent latencyBroadcast = new Intent(ACTION_NETWORK_CONDITIONS_MEASURED);
-        switch (mNetworkInfo.getType()) {
-            case ConnectivityManager.TYPE_WIFI:
-                WifiInfo currentWifiInfo = mWifiManager.getConnectionInfo();
-                if (currentWifiInfo != null) {
-                    // NOTE: getSSID()'s behavior changed in API 17; before that, SSIDs were not
-                    // surrounded by double quotation marks (thus violating the Javadoc), but this
-                    // was changed to match the Javadoc in API 17. Since clients may have started
-                    // sanitizing the output of this method since API 17 was released, we should
-                    // not change it here as it would become impossible to tell whether the SSID is
-                    // simply being surrounded by quotes due to the API, or whether those quotes
-                    // are actually part of the SSID.
-                    latencyBroadcast.putExtra(EXTRA_SSID, currentWifiInfo.getSSID());
-                    latencyBroadcast.putExtra(EXTRA_BSSID, currentWifiInfo.getBSSID());
-                } else {
-                    if (DBG) logw("network info is TYPE_WIFI but no ConnectionInfo found");
-                    return;
-                }
-                break;
-            case ConnectivityManager.TYPE_MOBILE:
-                latencyBroadcast.putExtra(EXTRA_NETWORK_TYPE, mTelephonyManager.getNetworkType());
-                List<CellInfo> info = mTelephonyManager.getAllCellInfo();
-                if (info == null) return;
-                int numRegisteredCellInfo = 0;
-                for (CellInfo cellInfo : info) {
-                    if (cellInfo.isRegistered()) {
-                        numRegisteredCellInfo++;
-                        if (numRegisteredCellInfo > 1) {
-                            if (DBG) log("more than one registered CellInfo.  Can't " +
-                                    "tell which is active.  Bailing.");
-                            return;
-                        }
-                        if (cellInfo instanceof CellInfoCdma) {
-                            CellIdentityCdma cellId = ((CellInfoCdma) cellInfo).getCellIdentity();
-                            latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId);
-                        } else if (cellInfo instanceof CellInfoGsm) {
-                            CellIdentityGsm cellId = ((CellInfoGsm) cellInfo).getCellIdentity();
-                            latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId);
-                        } else if (cellInfo instanceof CellInfoLte) {
-                            CellIdentityLte cellId = ((CellInfoLte) cellInfo).getCellIdentity();
-                            latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId);
-                        } else if (cellInfo instanceof CellInfoWcdma) {
-                            CellIdentityWcdma cellId = ((CellInfoWcdma) cellInfo).getCellIdentity();
-                            latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId);
-                        } else {
-                            if (DBG) logw("Registered cellinfo is unrecognized");
-                            return;
-                        }
-                    }
-                }
-                break;
-            default:
-                return;
-        }
-        latencyBroadcast.putExtra(EXTRA_CONNECTIVITY_TYPE, mNetworkInfo.getType());
-        latencyBroadcast.putExtra(EXTRA_RESPONSE_RECEIVED, responseReceived);
-        latencyBroadcast.putExtra(EXTRA_REQUEST_TIMESTAMP_MS, requestTimestampMs);
-
-        if (responseReceived) {
-            latencyBroadcast.putExtra(EXTRA_IS_CAPTIVE_PORTAL, isCaptivePortal);
-            latencyBroadcast.putExtra(EXTRA_RESPONSE_TIMESTAMP_MS, responseTimestampMs);
-        }
-        mContext.sendBroadcast(latencyBroadcast, PERMISSION_ACCESS_NETWORK_CONDITIONS);
-    }
-}
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index d6ee8e0..6d4a302 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -312,6 +312,11 @@
      */
     void setDnsServersForNetwork(int netId, in String[] servers, String domains);
 
+    /**
+     * Flush the DNS cache associated with the specified network.
+     */
+    void flushNetworkDnsCache(int netId);
+
     void setFirewallEnabled(boolean enabled);
     boolean isFirewallEnabled();
     void setFirewallInterfaceRule(String iface, boolean allow);
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index dda6d27..6334f76 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -716,6 +716,19 @@
             = "android.os.action.POWER_SAVE_MODE_CHANGED";
 
     /**
+     * Intent that is broadcast when the state of {@link #isPowerSaveMode()} is about to change.
+     * This broadcast is only sent to registered receivers.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_POWER_SAVE_MODE_CHANGING
+            = "android.os.action.POWER_SAVE_MODE_CHANGING";
+
+    /** @hide */
+    public static final String EXTRA_POWER_SAVE_MODE = "mode";
+
+    /**
      * A wake lock is a mechanism to indicate that your application needs
      * to have the device stay on.
      * <p>
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 13f93a7..04e6227 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -755,17 +755,50 @@
     /**
      * If the target user is a managed profile of the calling user or the caller
      * is itself a managed profile, then this returns a badged copy of the given
-     * icon to be able to distinguish it from the original icon.
-     * <P>
-     * If the original drawable is not a BitmapDrawable, then the original
-     * drawable is returned.
-     * </P>
+     * icon to be able to distinguish it from the original icon. For badging an
+     * arbitrary drawable use {@link #getBadgedDrawableForUser(
+     * android.graphics.drawable.Drawable, UserHandle, android.graphics.Rect, int)}.
+     * <p>
+     * If the original drawable is a BitmapDrawable and the backing bitmap is
+     * mutable as per {@link android.graphics.Bitmap#isMutable()}, the bading
+     * is performed in place and the original drawable is returned.
+     * </p>
      *
      * @param icon The icon to badge.
      * @param user The target user.
      * @return A drawable that combines the original icon and a badge as
      *         determined by the system.
      */
+    public Drawable getBadgedIconForUser(Drawable icon, UserHandle user) {
+        final int badgeResId = getBadgeResIdForUser(user.getIdentifier());
+        if (badgeResId == 0) {
+            return icon;
+        }
+        Drawable badgeIcon = mContext.getPackageManager()
+                .getDrawable("system", badgeResId, null);
+        return getBadgedDrawable(icon, badgeIcon, null, true);
+    }
+
+    /**
+     * If the target user is a managed profile of the calling user or the caller
+     * is itself a managed profile, then this returns a badged copy of the given
+     * icon to be able to distinguish it from the original icon.
+     * <p>
+     * If the original drawable is not a BitmapDrawable, then the original
+     * drawable is returned.
+     * </p>
+     *
+     * @param icon The icon to badge.
+     * @param user The target user.
+     * @return A drawable that combines the original icon and a badge as
+     *         determined by the system.
+     *
+     * @deprecation Use {@link #getBadgedIconForUser(
+     *     android.graphics.drawable.Drawable, UserHandle)}
+     *
+     * @hide
+     */
+    @Deprecated
     public Drawable getBadgedDrawableForUser(Drawable icon, UserHandle user) {
         int badgeResId = getBadgeResIdForUser(user.getIdentifier());
         if (badgeResId == 0) {
@@ -773,12 +806,45 @@
         } else {
             Drawable badgeIcon = mContext.getPackageManager()
                     .getDrawable("system", badgeResId, null);
-            return getMergedDrawable(icon, badgeIcon);
+            return getBadgedDrawable(icon, badgeIcon, null, false);
         }
     }
 
     /**
      * If the target user is a managed profile of the calling user or the caller
+     * is itself a managed profile, then this returns a badged copy of the given
+     * drawable allowing the user to distinguish it from the original drawable.
+     * The caller can specify the location in the bounds of the drawable to be
+     * badged where the badge should be applied as well as the density of the
+     * badge to be used.
+     * <p>
+     * If the original drawable is a BitmapDrawable and the backing bitmap is
+     * mutable as per {@link android.graphics.Bitmap#isMutable()}, the bading
+     * is performed in place and the original drawable is returned.
+     * </p>
+     *
+     * @param badgedDrawable The drawable to badge.
+     * @param user The target user.
+     * @param badgeLocation Where in the bounds of the badged drawable to place
+     *         the badge. If not provided, the badge is applied on top of the entire
+     *         drawable being badged.
+     * @param badgeDensity The optional desired density for the badge as per
+     *         {@link android.util.DisplayMetrics#densityDpi}. If not provided,
+     *         the density of the display is used.
+     * @return A drawable that combines the original drawable and a badge as
+     *         determined by the system.
+     */
+    public Drawable getBadgedDrawableForUser(Drawable badgedDrawable, UserHandle user,
+            Rect badgeLocation, int badgeDensity) {
+        Drawable badgeDrawable = getBadgeForUser(user, badgeDensity);
+        if (badgeDrawable == null) {
+            return badgedDrawable;
+        }
+        return getBadgedDrawable(badgedDrawable, badgeDrawable, badgeLocation, true);
+    }
+
+    /**
+     * If the target user is a managed profile of the calling user or the caller
      * is itself a managed profile, then this returns a copy of the label with
      * badging for accessibility services like talkback. E.g. passing in "Email"
      * and it might return "Work Email" for Email in the work profile.
@@ -812,14 +878,20 @@
      * icon to include in a view to distinguish it from the original icon.
      *
      * @param user The target user.
+     * @param density The optional desired density for the badge as per
+     *         {@link android.util.DisplayMetrics#densityDpi}. If not provided
+     *         the density of the current display is used.
      * @return the drawable or null if no drawable is required.
      * @hide
      */
-    public Drawable getBadgeForUser(UserHandle user) {
+    public Drawable getBadgeForUser(UserHandle user, int density) {
         UserInfo userInfo = getUserIfProfile(user.getIdentifier());
         if (userInfo != null && userInfo.isManagedProfile()) {
-            return Resources.getSystem().getDrawable(
-                    com.android.internal.R.drawable.ic_corp_badge);
+            if (density <= 0) {
+                density = mContext.getResources().getDisplayMetrics().densityDpi;
+            }
+            return Resources.getSystem().getDrawableForDensity(
+                    com.android.internal.R.drawable.ic_corp_badge, density);
         }
         return null;
     }
@@ -847,20 +919,57 @@
         return null;
     }
 
-    private Drawable getMergedDrawable(Drawable icon, Drawable badge) {
-        final int width = icon.getIntrinsicWidth();
-        final int height = icon.getIntrinsicHeight();
-        Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
-        Canvas canvas = new Canvas(bitmap);
-        icon.setBounds(0, 0, width, height);
-        icon.draw(canvas);
-        badge.setBounds(0, 0, width, height);
-        badge.draw(canvas);
-        BitmapDrawable merged = new BitmapDrawable(bitmap);
-        if (icon instanceof BitmapDrawable) {
-            merged.setTargetDensity(((BitmapDrawable) icon).getBitmap().getDensity());
+    private Drawable getBadgedDrawable(Drawable badgedDrawable, Drawable badgeDrawable,
+            Rect badgeLocation, boolean tryBadgeInPlace) {
+        final int badgedWidth = badgedDrawable.getIntrinsicWidth();
+        final int badgedHeight = badgedDrawable.getIntrinsicHeight();
+        final boolean canBadgeInPlace = tryBadgeInPlace
+                && (badgedDrawable instanceof BitmapDrawable)
+                && ((BitmapDrawable) badgedDrawable).getBitmap().isMutable();
+
+        final Bitmap bitmap;
+        if (canBadgeInPlace) {
+            bitmap = ((BitmapDrawable) badgedDrawable).getBitmap();
+        } else {
+            bitmap = Bitmap.createBitmap(badgedWidth, badgedHeight, Config.ARGB_8888);
         }
-        return merged;
+        Canvas canvas = new Canvas(bitmap);
+
+        if (!canBadgeInPlace) {
+            badgedDrawable.setBounds(0, 0, badgedWidth, badgedHeight);
+            badgedDrawable.draw(canvas);
+        }
+
+        if (badgeLocation != null) {
+            if (badgeLocation.left < 0 || badgeLocation.top < 0
+                    || badgeLocation.right > badgedWidth || badgeLocation.bottom > badgedHeight) {
+                throw new IllegalArgumentException("Badge location " + badgeLocation
+                        + " not in badged drawable bounds "
+                        + new Rect(0, 0, badgedWidth, badgedHeight));
+            }
+            badgeDrawable.setBounds(0, 0, badgeLocation.width(), badgeLocation.height());
+
+            canvas.save();
+            canvas.translate(badgeLocation.left, badgeLocation.top);
+            badgeDrawable.draw(canvas);
+            canvas.restore();
+        } else {
+            badgeDrawable.setBounds(0, 0, badgedWidth, badgedHeight);
+            badgeDrawable.draw(canvas);
+        }
+
+        if (!canBadgeInPlace) {
+            BitmapDrawable mergedDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
+
+            if (badgedDrawable instanceof BitmapDrawable) {
+                BitmapDrawable bitmapDrawable = (BitmapDrawable) badgedDrawable;
+                mergedDrawable.setTargetDensity(bitmapDrawable.getBitmap().getDensity());
+            }
+
+            return mergedDrawable;
+        }
+
+        return badgedDrawable;
     }
 
     /**
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 1bec285..7e1c069 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1126,18 +1126,17 @@
          * import android.provider.ContactsContract.Contacts;
          *
          * Uri uri = Contacts.CONTENT_URI.buildUpon()
-         *          .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true")
+         *          .appendQueryParameter(Contacts.ADDRESS_BOOK_INDEX_EXTRAS, "true")
          *          .build();
          * Cursor cursor = getContentResolver().query(uri,
          *          new String[] {Contacts.DISPLAY_NAME},
          *          null, null, null);
          * Bundle bundle = cursor.getExtras();
-         * if (bundle.containsKey(Contacts.ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_TITLES) &&
-         *         bundle.containsKey(Contacts.ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS)) {
+         * if (bundle.containsKey(Contacts.EXTRA_ADDRESS_BOOK_INDEX_TITLES) &&
+         *         bundle.containsKey(Contacts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS)) {
          *     String sections[] =
-         *             bundle.getStringArray(Contacts.ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_TITLES);
-         *     int counts[] = bundle.getIntArray(
-         *             Contacts.ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS);
+         *             bundle.getStringArray(Contacts.EXTRA_ADDRESS_BOOK_INDEX_TITLES);
+         *     int counts[] = bundle.getIntArray(Contacts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS);
          * }
          * </pre>
          * </p>
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 5d5be4a..de1df56 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4607,6 +4607,12 @@
         public static final String WAKE_GESTURE_ENABLED = "wake_gesture_enabled";
 
         /**
+         * Whether the device should doze if configured.
+         * @hide
+         */
+        public static final String DOZE_ENABLED = "doze_enabled";
+
+        /**
          * The current night mode that has been selected by the user.  Owned
          * and controlled by UiModeManagerService.  Constants are as per
          * UiModeManager.
@@ -4716,6 +4722,13 @@
         public static final String UNSAFE_VOLUME_MUSIC_ACTIVE_MS = "unsafe_volume_music_active_ms";
 
         /**
+         * This preference enables notification display on the lockscreen.
+         * @hide
+         */
+        public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS =
+                "lock_screen_show_notifications";
+
+        /**
          * This are the settings to be backed up.
          *
          * NOTE: Settings are backed up and restored in the order they appear
@@ -6359,15 +6372,6 @@
          */
         public static final String POLICY_CONTROL = "policy_control";
 
-
-        /**
-         * This preference enables notification display even over a securely
-         * locked screen.
-         * @hide
-         */
-        public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS =
-                "lock_screen_show_notifications";
-
         /**
          * Defines global zen mode.  ZEN_MODE_OFF, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
          * or ZEN_MODE_NO_INTERRUPTIONS.
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 1f01bc8..f807ad6 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -609,8 +609,12 @@
         }
 
         private boolean isAmbient(String key) {
+            int firstAmbientIndex = mRankingUpdate.getFirstAmbientIndex();
+            if (firstAmbientIndex < 0) {
+                return false;
+            }
             int rank = getRank(key);
-            return rank >= 0 && rank >= mRankingUpdate.getFirstAmbientIndex();
+            return rank >= 0 && rank >= firstAmbientIndex;
         }
 
         private boolean isIntercepted(String key) {
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index e5a5292..0eda692 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -63,7 +63,6 @@
         this.score = score;
         this.notification = notification;
         this.user = user;
-        this.notification.setUser(user);
         this.postTime = postTime;
         this.key = key();
         this.groupKey = groupKey();
@@ -83,7 +82,6 @@
         this.score = in.readInt();
         this.notification = new Notification(in);
         this.user = UserHandle.readFromParcel(in);
-        this.notification.setUser(this.user);
         this.postTime = in.readLong();
         this.key = key();
         this.groupKey = groupKey();
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index 6278e69..b0ff947 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -16,6 +16,9 @@
 
 package android.service.voice;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Intent;
 import android.hardware.soundtrigger.IRecognitionStatusCallback;
 import android.hardware.soundtrigger.KeyphraseEnrollmentInfo;
@@ -27,6 +30,7 @@
 import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
 import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
 import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
+import android.media.AudioFormat;
 import android.os.AsyncTask;
 import android.os.Handler;
 import android.os.Message;
@@ -35,6 +39,9 @@
 
 import com.android.internal.app.IVoiceInteractionManagerService;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * A class that lets a VoiceInteractionService implementation interact with
  * always-on keyphrase detection APIs.
@@ -50,14 +57,17 @@
     /**
      * Indicates that recognition for the given keyphrase is not available on the system
      * because of the hardware configuration.
+     * No further interaction should be performed with the detector that returns this availability.
      */
     public static final int STATE_HARDWARE_UNAVAILABLE = -2;
     /**
      * Indicates that recognition for the given keyphrase is not supported.
+     * No further interaction should be performed with the detector that returns this availability.
      */
     public static final int STATE_KEYPHRASE_UNSUPPORTED = -1;
     /**
      * Indicates that the given keyphrase is not enrolled.
+     * The caller may choose to begin an enrollment flow for the keyphrase.
      */
     public static final int STATE_KEYPHRASE_UNENROLLED = 1;
     /**
@@ -72,6 +82,15 @@
     private static final int STATE_NOT_READY = 0;
 
     // Keyphrase management actions. Used in getManageIntent() ----//
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {
+                MANAGE_ACTION_ENROLL,
+                MANAGE_ACTION_RE_ENROLL,
+                MANAGE_ACTION_UN_ENROLL
+            })
+    public @interface ManageActions {}
+
     /** Indicates that we need to enroll. */
     public static final int MANAGE_ACTION_ENROLL = 0;
     /** Indicates that we need to re-enroll. */
@@ -79,7 +98,17 @@
     /** Indicates that we need to un-enroll. */
     public static final int MANAGE_ACTION_UN_ENROLL = 2;
 
-    //-- Flags for startRecogntion    ----//
+    //-- Flags for startRecognition    ----//
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true,
+            value = {
+                RECOGNITION_FLAG_NONE,
+                RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO,
+                RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS
+            })
+    public @interface RecognitionFlags {}
+
     /** Empty flag for {@link #startRecognition(int)}. */
     public static final int RECOGNITION_FLAG_NONE = 0;
     /**
@@ -87,17 +116,37 @@
      * whether the trigger audio for hotword needs to be captured.
      */
     public static final int RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO = 0x1;
+    /**
+     * Recognition flag for {@link #startRecognition(int)} that indicates
+     * whether the recognition should keep going on even after the keyphrase triggers.
+     * If this flag is specified, it's possible to get multiple triggers after a
+     * call to {@link #startRecognition(int)} if the user speaks the keyphrase multiple times.
+     * When this isn't specified, the default behavior is to stop recognition once the
+     * keyphrase is spoken, till the caller starts recognition again.
+     */
+    public static final int RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS = 0x2;
 
     //---- Recognition mode flags. Return codes for getSupportedRecognitionModes() ----//
     // Must be kept in sync with the related attribute defined as searchKeyphraseRecognitionFlags.
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true,
+            value = {
+                RECOGNITION_MODE_VOICE_TRIGGER,
+                RECOGNITION_MODE_USER_IDENTIFICATION,
+            })
+    public @interface RecognitionModes {}
+
     /**
-     * Simple recognition of the key phrase. Returned by {@link #getSupportedRecognitionModes()}
+     * Simple recognition of the key phrase.
+     * Returned by {@link #getSupportedRecognitionModes()}
      */
     public static final int RECOGNITION_MODE_VOICE_TRIGGER
             = SoundTrigger.RECOGNITION_MODE_VOICE_TRIGGER;
     /**
-     * Trigger only if one user is identified. Returned by {@link #getSupportedRecognitionModes()}
+     * User identification performed with the keyphrase recognition.
+     * Returned by {@link #getSupportedRecognitionModes()}
      */
     public static final int RECOGNITION_MODE_USER_IDENTIFICATION
             = SoundTrigger.RECOGNITION_MODE_USER_IDENTIFICATION;
@@ -109,16 +158,9 @@
     private static final int STATUS_ERROR = SoundTrigger.STATUS_ERROR;
     private static final int STATUS_OK = SoundTrigger.STATUS_OK;
 
-    private static final int MSG_STATE_CHANGED = 1;
+    private static final int MSG_AVAILABILITY_CHANGED = 1;
     private static final int MSG_HOTWORD_DETECTED = 2;
-    private static final int MSG_DETECTION_STARTED = 3;
-    private static final int MSG_DETECTION_STOPPED = 4;
-    private static final int MSG_DETECTION_ERROR = 5;
-
-    private static final int FLAG_REQUESTED = 0x1;
-    private static final int FLAG_STARTED = 0x2;
-    private static final int FLAG_CALL_ACTIVE = 0x4;
-    private static final int FLAG_MICROPHONE_OPEN = 0x8;
+    private static final int MSG_DETECTION_ERROR = 3;
 
     private final String mText;
     private final String mLocale;
@@ -136,8 +178,27 @@
     private final Handler mHandler;
 
     private int mAvailability = STATE_NOT_READY;
-    private int mInternalState = 0;
-    private int mRecognitionFlags = RECOGNITION_FLAG_NONE;
+
+    /**
+     * Details of the audio that triggered the keyphrase.
+     */
+    public static class TriggerAudio {
+        /**
+         * Format of {@code data}.
+         */
+        @NonNull
+        public final AudioFormat audioFormat;
+        /**
+         * Raw audio data that triggered they keyphrase.
+         */
+        @NonNull
+        public final byte[] data;
+
+        private TriggerAudio(AudioFormat _audioFormat, byte[] _data) {
+            audioFormat = _audioFormat;
+            data = _data;
+        }
+    }
 
     /**
      * Callbacks for always-on hotword detection.
@@ -150,13 +211,11 @@
          *
          * Availability implies whether the hardware on this system is capable of listening for
          * the given keyphrase or not. <p/>
-         * If the return code is one of {@link #STATE_HARDWARE_UNAVAILABLE} or
-         * {@link #STATE_KEYPHRASE_UNSUPPORTED},
-         * detection is not possible and no further interaction should be
-         * performed with this detector. <br/>
-         * If it is {@link #STATE_KEYPHRASE_UNENROLLED} the caller may choose to begin
-         * an enrollment flow for the keyphrase. <br/>
-         * and for {@link #STATE_KEYPHRASE_ENROLLED} a recognition can be started as desired. <p/>
+         *
+         * @see AlwaysOnHotwordDetector#STATE_HARDWARE_UNAVAILABLE
+         * @see AlwaysOnHotwordDetector#STATE_KEYPHRASE_UNSUPPORTED
+         * @see AlwaysOnHotwordDetector#STATE_KEYPHRASE_UNENROLLED
+         * @see AlwaysOnHotwordDetector#STATE_KEYPHRASE_ENROLLED
          */
         void onAvailabilityChanged(int status);
         /**
@@ -165,22 +224,10 @@
          * Clients should start a recognition again once they are done handling this
          * detection.
          *
-         * @param data Optional trigger audio data, if it was requested during
+         * @param triggerAudio Optional trigger audio data, if it was requested during
          *        {@link AlwaysOnHotwordDetector#startRecognition(int)}.
          */
-        void onDetected(byte[] data);
-        /**
-         * Called when the detection for the associated keyphrase starts.
-         * This is called as a result of a successful call to
-         * {@link AlwaysOnHotwordDetector#startRecognition(int)}.
-         */
-        void onDetectionStarted();
-        /**
-         * Called when the detection for the associated keyphrase stops.
-         * This is called as a result of a successful call to
-         * {@link AlwaysOnHotwordDetector#stopRecognition()}.
-         */
-        void onDetectionStopped();
+        void onDetected(@Nullable TriggerAudio triggerAudio);
         /**
          * Called when the detection fails due to an error.
          */
@@ -215,6 +262,9 @@
     /**
      * Gets the recognition modes supported by the associated keyphrase.
      *
+     * @see #RECOGNITION_MODE_USER_IDENTIFICATION
+     * @see #RECOGNITION_MODE_VOICE_TRIGGER
+     *
      * @throws UnsupportedOperationException if the keyphrase itself isn't supported.
      *         Callers should only call this method after a supported state callback on
      *         {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
@@ -222,7 +272,8 @@
      *         This may happen if another detector has been instantiated or the
      *         {@link VoiceInteractionService} hosting this detector has been shut down.
      */
-    public int getSupportedRecognitionModes() {
+    public @RecognitionModes int getSupportedRecognitionModes() {
+        if (DBG) Slog.d(TAG, "getSupportedRecognitionModes()");
         synchronized (mLock) {
             return getSupportedRecognitionModesLocked();
         }
@@ -248,8 +299,10 @@
      * Starts recognition for the associated keyphrase.
      *
      * @param recognitionFlags The flags to control the recognition properties.
-     *        The allowed flags are {@link #RECOGNITION_FLAG_NONE} and
-     *        {@link #RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO}.
+     *        The allowed flags are {@link #RECOGNITION_FLAG_NONE},
+     *        {@link #RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO} and
+     *        {@link #RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS}.
+     * @return Indicates whether the call succeeded or not.
      * @throws UnsupportedOperationException if the recognition isn't supported.
      *         Callers should only call this method after a supported state callback on
      *         {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
@@ -257,7 +310,8 @@
      *         This may happen if another detector has been instantiated or the
      *         {@link VoiceInteractionService} hosting this detector has been shut down.
      */
-    public void startRecognition(int recognitionFlags) {
+    public boolean startRecognition(@RecognitionFlags int recognitionFlags) {
+        if (DBG) Slog.d(TAG, "startRecognition(" + recognitionFlags + ")");
         synchronized (mLock) {
             if (mAvailability == STATE_INVALID) {
                 throw new IllegalStateException("startRecognition called on an invalid detector");
@@ -269,15 +323,14 @@
                         "Recognition for the given keyphrase is not supported");
             }
 
-            mInternalState |= FLAG_REQUESTED;
-            mRecognitionFlags = recognitionFlags;
-            updateRecognitionLocked();
+            return startRecognitionLocked(recognitionFlags) == STATUS_OK;
         }
     }
 
     /**
      * Stops recognition for the associated keyphrase.
      *
+     * @return Indicates whether the call succeeded or not.
      * @throws UnsupportedOperationException if the recognition isn't supported.
      *         Callers should only call this method after a supported state callback on
      *         {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
@@ -285,7 +338,8 @@
      *         This may happen if another detector has been instantiated or the
      *         {@link VoiceInteractionService} hosting this detector has been shut down.
      */
-    public void stopRecognition() {
+    public boolean stopRecognition() {
+        if (DBG) Slog.d(TAG, "stopRecognition()");
         synchronized (mLock) {
             if (mAvailability == STATE_INVALID) {
                 throw new IllegalStateException("stopRecognition called on an invalid detector");
@@ -297,9 +351,7 @@
                         "Recognition for the given keyphrase is not supported");
             }
 
-            mInternalState &= ~FLAG_REQUESTED;
-            mRecognitionFlags = RECOGNITION_FLAG_NONE;
-            updateRecognitionLocked();
+            return stopRecognitionLocked() == STATUS_OK;
         }
     }
 
@@ -317,7 +369,8 @@
      *         This may happen if another detector has been instantiated or the
      *         {@link VoiceInteractionService} hosting this detector has been shut down.
      */
-    public Intent getManageIntent(int action) {
+    public Intent getManageIntent(@ManageActions int action) {
+        if (DBG) Slog.d(TAG, "getManageIntent(" + action + ")");
         synchronized (mLock) {
             return getManageIntentLocked(action);
         }
@@ -364,7 +417,7 @@
      */
     void onSoundModelsChanged() {
         synchronized (mLock) {
-            // TODO: This should stop the recognition if it was using an enrolled sound model
+            // FIXME: This should stop the recognition if it was using an enrolled sound model
             // that's no longer available.
             if (mAvailability == STATE_INVALID
                     || mAvailability == STATE_HARDWARE_UNAVAILABLE
@@ -378,87 +431,21 @@
         }
     }
 
-    @SuppressWarnings("unused")
-    private void onCallStateChanged(boolean active) {
-        synchronized (mLock) {
-            if (active) {
-                mInternalState |= FLAG_CALL_ACTIVE;
-            } else {
-                mInternalState &= ~FLAG_CALL_ACTIVE;
-            }
-
-            updateRecognitionLocked();
-        }
-    }
-
-    @SuppressWarnings("unused")
-    private void onMicrophoneStateChanged(boolean open) {
-        synchronized (mLock) {
-            if (open) {
-                mInternalState |= FLAG_MICROPHONE_OPEN;
-            } else {
-                mInternalState &= ~FLAG_MICROPHONE_OPEN;
-            }
-
-            updateRecognitionLocked();
-        }
-    }
-
-    private void updateRecognitionLocked() {
-        // Don't attempt to update the recognition state if keyphrase isn't enrolled.
-        if (mAvailability != STATE_KEYPHRASE_ENROLLED) {
-            return;
-        }
-
-        // Start recognition if requested and not in a call/reading from the microphone
-        boolean start = (mInternalState&FLAG_REQUESTED) != 0
-                && (mInternalState&FLAG_CALL_ACTIVE) == 0
-                && (mInternalState&FLAG_MICROPHONE_OPEN) == 0;
-        boolean requested = (mInternalState&FLAG_REQUESTED) != 0;
-
-        if (start && (mInternalState&FLAG_STARTED) == 0) {
-            // Start recognition.
-            if (DBG) Slog.d(TAG, "starting recognition...");
-            int status = startRecognitionLocked();
-            if (status == STATUS_OK) {
-                mHandler.sendEmptyMessage(MSG_DETECTION_STARTED);
-            } else {
-                if (DBG) Slog.d(TAG, "failed to start recognition: " + status);
-                mHandler.sendEmptyMessage(MSG_DETECTION_ERROR);
-            }
-            // Post the callback
-            return;
-        }
-
-        if (!start && (mInternalState&FLAG_STARTED) != 0) {
-            // Stop recognition
-            // Only notify the callback if a recognition was *not* requested.
-            // For internal stoppages, don't notify the callback.
-            if (DBG) Slog.d(TAG, "stopping recognition...");
-            int status = stopRecognitionLocked();
-            if (status == STATUS_OK) {
-                if (!requested) mHandler.sendEmptyMessage(MSG_DETECTION_STOPPED);
-            } else {
-                if (!requested) mHandler.sendEmptyMessage(MSG_DETECTION_ERROR);
-                if (DBG) Slog.d(TAG, "failed to stop recognition: " + status);
-            }
-            return;
-        }
-    }
-
-    private int startRecognitionLocked() {
+    private int startRecognitionLocked(int recognitionFlags) {
         KeyphraseRecognitionExtra[] recognitionExtra = new KeyphraseRecognitionExtra[1];
         // TODO: Do we need to do something about the confidence level here?
         recognitionExtra[0] = new KeyphraseRecognitionExtra(mKeyphraseMetadata.id,
-                mKeyphraseMetadata.recognitionModeFlags, new ConfidenceLevel[0]);
+                mKeyphraseMetadata.recognitionModeFlags, 0, new ConfidenceLevel[0]);
         boolean captureTriggerAudio =
-                (mRecognitionFlags&RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO) != 0;
+                (recognitionFlags&RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO) != 0;
+        boolean allowMultipleTriggers =
+                (recognitionFlags&RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS) != 0;
         int code = STATUS_ERROR;
         try {
             code = mModelManagementService.startRecognition(mVoiceInteractionService,
                     mKeyphraseMetadata.id, mInternalCallback,
-                    new RecognitionConfig(
-                            captureTriggerAudio, recognitionExtra, null /* additional data */));
+                    new RecognitionConfig(captureTriggerAudio, allowMultipleTriggers,
+                            recognitionExtra, null /* additional data */));
         } catch (RemoteException e) {
             Slog.w(TAG, "RemoteException in startRecognition!");
         }
@@ -484,7 +471,7 @@
     }
 
     private void notifyStateChangedLocked() {
-        Message message = Message.obtain(mHandler, MSG_STATE_CHANGED);
+        Message message = Message.obtain(mHandler, MSG_AVAILABILITY_CHANGED);
         message.arg1 = mAvailability;
         message.sendToTarget();
     }
@@ -499,9 +486,22 @@
 
         @Override
         public void onDetected(KeyphraseRecognitionEvent event) {
-            Slog.i(TAG, "onDetected");
+            if (DBG) {
+                Slog.d(TAG, "OnDetected(" + event + ")");
+            } else {
+                Slog.i(TAG, "onDetected");
+            }
             Message message = Message.obtain(mHandler, MSG_HOTWORD_DETECTED);
-            message.obj = event.data;
+            // FIXME: Check whether the event contains trigger data or not.
+            // FIXME: Read the audio format from the event.
+            if (event.data != null) {
+                AudioFormat audioFormat = new AudioFormat.Builder()
+                        .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
+                        .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
+                        .setSampleRate(16000)
+                        .build();
+                message.obj = new TriggerAudio(audioFormat, event.data);
+            }
             message.sendToTarget();
         }
 
@@ -523,34 +523,13 @@
             }
 
             switch (msg.what) {
-                case MSG_STATE_CHANGED:
+                case MSG_AVAILABILITY_CHANGED:
                     mExternalCallback.onAvailabilityChanged(msg.arg1);
                     break;
                 case MSG_HOTWORD_DETECTED:
-                    synchronized (mLock) {
-                        mInternalState &= ~FLAG_REQUESTED;
-                        mInternalState &= ~FLAG_STARTED;
-                    }
-                    mExternalCallback.onDetected((byte[]) msg.obj);
-                    break;
-                case MSG_DETECTION_STARTED:
-                    synchronized (mLock) {
-                        mInternalState |= FLAG_STARTED;
-                    }
-                    mExternalCallback.onDetectionStarted();
-                    break;
-                case MSG_DETECTION_STOPPED:
-                    synchronized (mLock) {
-                        mInternalState &= ~FLAG_REQUESTED;
-                        mInternalState &= ~FLAG_STARTED;
-                    }
-                    mExternalCallback.onDetectionStopped();
+                    mExternalCallback.onDetected((TriggerAudio) msg.obj);
                     break;
                 case MSG_DETECTION_ERROR:
-                    synchronized (mLock) {
-                        mInternalState &= ~FLAG_REQUESTED;
-                        mInternalState &= ~FLAG_STARTED;
-                    }
                     mExternalCallback.onError();
                     break;
                 default:
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 82e23c4..5189404 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -182,6 +182,7 @@
     /**
      * Called during service de-initialization to tell you when the system is shutting the
      * service down.
+     * At this point this service may no longer be the active {@link VoiceInteractionService}.
      */
     public void onShutdown() {
     }
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 0075d0b..7245975 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -2029,6 +2029,11 @@
                             mParams.putString(Engine.KEY_PARAM_LANGUAGE, defaultLanguage[0]);
                             mParams.putString(Engine.KEY_PARAM_COUNTRY, defaultLanguage[1]);
                             mParams.putString(Engine.KEY_PARAM_VARIANT, defaultLanguage[2]);
+
+                            // Get the default voice for the locale.
+                            String defaultVoiceName = mService.getDefaultVoiceNameFor(
+                                defaultLanguage[0], defaultLanguage[1], defaultLanguage[2]);
+                            mParams.putString(Engine.KEY_PARAM_VOICE_NAME, defaultVoiceName);
                         }
 
                         Log.i(TAG, "Set up connection to " + mName);
diff --git a/core/java/android/text/style/TtsSpan.java b/core/java/android/text/style/TtsSpan.java
index f3a48a6..cb447fd 100644
--- a/core/java/android/text/style/TtsSpan.java
+++ b/core/java/android/text/style/TtsSpan.java
@@ -518,7 +518,7 @@
      * This class uses generics so methods from this class can return instances
      * of its child classes, resulting in a fluent API (CRTP pattern).
      */
-    public static abstract class Builder<C extends Builder<C>> {
+    public static class Builder<C extends Builder<?>> {
         // Holds the type of this class.
         private final String mType;
 
@@ -580,7 +580,7 @@
      * this builder like {@link TtsSpan.TextBuilder} and
      * {@link TtsSpan.CardinalBuilder} are likely more useful.
      */
-    public static class SemioticClassBuilder<C extends SemioticClassBuilder<C>>
+    public static class SemioticClassBuilder<C extends SemioticClassBuilder<?>>
             extends Builder<C> {
 
         public SemioticClassBuilder(String type) {
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 154d227..cfb0297 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -26,6 +26,8 @@
 import android.util.DisplayMetrics;
 import android.util.Log;
 
+import java.util.Arrays;
+
 /**
  * Provides information about the size and density of a logical display.
  * <p>
@@ -613,6 +615,17 @@
     }
 
     /**
+     * Get the supported refresh rates of this display in frames per second.
+     */
+    public float[] getSupportedRefreshRates() {
+        synchronized (this) {
+            updateDisplayInfoLocked();
+            final float[] refreshRates = mDisplayInfo.supportedRefreshRates;
+            return Arrays.copyOf(refreshRates, refreshRates.length);
+        }
+    }
+
+    /**
      * Gets the app VSYNC offset, in nanoseconds.  This is a positive value indicating
      * the phase offset of the VSYNC events provided by Choreographer relative to the
      * display refresh.  For example, if Choreographer reports that the refresh occurred
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 98696c7..56a05fe 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -22,6 +22,9 @@
 import android.os.Parcelable;
 import android.util.DisplayMetrics;
 
+import java.util.Arrays;
+
+import libcore.util.EmptyArray;
 import libcore.util.Objects;
 
 /**
@@ -156,6 +159,11 @@
     public float refreshRate;
 
     /**
+     * The supported refresh rates of this display at the current resolution in frames per second.
+     */
+    public float[] supportedRefreshRates = EmptyArray.FLOAT;
+
+    /**
      * The logical display density which is the basis for density-independent
      * pixels.
      */
@@ -299,6 +307,8 @@
         overscanBottom = other.overscanBottom;
         rotation = other.rotation;
         refreshRate = other.refreshRate;
+        supportedRefreshRates = Arrays.copyOf(
+                other.supportedRefreshRates, other.supportedRefreshRates.length);
         logicalDensityDpi = other.logicalDensityDpi;
         physicalXDpi = other.physicalXDpi;
         physicalYDpi = other.physicalYDpi;
@@ -329,6 +339,7 @@
         overscanBottom = source.readInt();
         rotation = source.readInt();
         refreshRate = source.readFloat();
+        supportedRefreshRates = source.createFloatArray();
         logicalDensityDpi = source.readInt();
         physicalXDpi = source.readFloat();
         physicalYDpi = source.readFloat();
@@ -360,6 +371,7 @@
         dest.writeInt(overscanBottom);
         dest.writeInt(rotation);
         dest.writeFloat(refreshRate);
+        dest.writeFloatArray(supportedRefreshRates);
         dest.writeInt(logicalDensityDpi);
         dest.writeFloat(physicalXDpi);
         dest.writeFloat(physicalYDpi);
@@ -462,7 +474,9 @@
         sb.append(smallestNominalAppHeight);
         sb.append(", ");
         sb.append(refreshRate);
-        sb.append(" fps, rotation ");
+        sb.append(" fps, supportedRefreshRates ");
+        sb.append(Arrays.toString(supportedRefreshRates));
+        sb.append(", rotation ");
         sb.append(rotation);
         sb.append(", density ");
         sb.append(logicalDensityDpi);
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 8b2ec7a..681717c 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -1722,6 +1722,11 @@
         return false;
     }
 
+    /** @hide */
+    public static final boolean isMetaKey(int keyCode) {
+        return keyCode == KeyEvent.KEYCODE_META_LEFT || keyCode == KeyEvent.KEYCODE_META_RIGHT;
+    }
+
     /** {@inheritDoc} */
     @Override
     public final int getDeviceId() {
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 191ad64..1e28e33 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -74,6 +74,7 @@
             IBinder displayToken, int orientation,
             int l, int t, int r, int b,
             int L, int T, int R, int B);
+    private static native void nativeSetDisplaySize(IBinder displayToken, int width, int height);
     private static native SurfaceControl.PhysicalDisplayInfo[] nativeGetDisplayConfigs(
             IBinder displayToken);
     private static native int nativeGetActiveConfig(IBinder displayToken);
@@ -588,6 +589,17 @@
         }
     }
 
+    public static void setDisplaySize(IBinder displayToken, int width, int height) {
+        if (displayToken == null) {
+            throw new IllegalArgumentException("displayToken must not be null");
+        }
+        if (width <= 0 || height <= 0) {
+            throw new IllegalArgumentException("width and height must be positive");
+        }
+
+        nativeSetDisplaySize(displayToken, width, height);
+    }
+
     public static IBinder createDisplay(String name, boolean secure) {
         if (name == null) {
             throw new IllegalArgumentException("name must not be null");
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index d14f226..f9333d5 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -276,12 +276,12 @@
         if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
             HardwareCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
             try {
-                canvas.save();
+                final int saveCount = canvas.save();
                 canvas.translate(mInsetLeft, mInsetTop);
                 callbacks.onHardwarePreDraw(canvas);
                 canvas.drawRenderNode(view.getDisplayList());
                 callbacks.onHardwarePostDraw(canvas);
-                canvas.restore();
+                canvas.restoreToCount(saveCount);
                 mRootNodeNeedsUpdate = false;
             } finally {
                 mRootNode.end(canvas);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 7e16c7d..328d67c 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3176,7 +3176,7 @@
 
     @ViewDebug.ExportedProperty(deepExport = true, prefix = "bg_")
     private Drawable mBackground;
-    private ColorStateList mBackgroundTint = null;
+    private ColorStateList mBackgroundTintList = null;
     private PorterDuff.Mode mBackgroundTintMode = PorterDuff.Mode.SRC_ATOP;
     private boolean mHasBackgroundTint = false;
 
@@ -4016,7 +4016,7 @@
                     break;
                 case R.styleable.View_backgroundTint:
                     // This will get applied later during setBackground().
-                    mBackgroundTint = a.getColorStateList(R.styleable.View_backgroundTint);
+                    mBackgroundTintList = a.getColorStateList(R.styleable.View_backgroundTint);
                     mHasBackgroundTint = true;
                     break;
                 case R.styleable.View_backgroundTintMode:
@@ -10830,13 +10830,14 @@
         // Unattached views ignore this signal, and outline is recomputed in onAttachedToWindow()
         if (mAttachInfo == null) return;
 
-        final Outline outline = mAttachInfo.mTmpOutline;
-        outline.setEmpty();
-
         if (mOutlineProvider == null) {
             // no provider, remove outline
             mRenderNode.setOutline(null);
         } else {
+            final Outline outline = mAttachInfo.mTmpOutline;
+            outline.setEmpty();
+            outline.setAlpha(1.0f);
+
             mOutlineProvider.getOutline(this, outline);
             mRenderNode.setOutline(outline);
         }
@@ -14646,8 +14647,9 @@
                         } else  if (layerType == LAYER_TYPE_NONE) {
                             final int scrollX = hasDisplayList ? 0 : sx;
                             final int scrollY = hasDisplayList ? 0 : sy;
-                            canvas.saveLayerAlpha(scrollX, scrollY, scrollX + mRight - mLeft,
-                                    scrollY + mBottom - mTop, multipliedAlpha, layerFlags);
+                            canvas.saveLayerAlpha(scrollX, scrollY,
+                                    scrollX + (mRight - mLeft), scrollY + (mBottom - mTop),
+                                    multipliedAlpha, layerFlags);
                         }
                     } else {
                         // Alpha is handled by the child directly, clobber the layer's alpha
@@ -14660,19 +14662,29 @@
             mPrivateFlags &= ~PFLAG_ALPHA_SET;
         }
 
-        if ((flags & ViewGroup.FLAG_CLIP_CHILDREN) == ViewGroup.FLAG_CLIP_CHILDREN &&
-                !usingRenderNodeProperties && cache == null) {
-            if (offsetForScroll) {
-                canvas.clipRect(sx, sy, sx + (mRight - mLeft), sy + (mBottom - mTop));
-            } else {
-                if (!scalingRequired || cache == null) {
-                    canvas.clipRect(0, 0, mRight - mLeft, mBottom - mTop);
+        if (!usingRenderNodeProperties) {
+            // apply clips directly, since RenderNode won't do it for this draw
+            if ((flags & ViewGroup.FLAG_CLIP_CHILDREN) == ViewGroup.FLAG_CLIP_CHILDREN
+                    && cache == null) {
+                if (offsetForScroll) {
+                    canvas.clipRect(sx, sy, sx + (mRight - mLeft), sy + (mBottom - mTop));
                 } else {
-                    canvas.clipRect(0, 0, cache.getWidth(), cache.getHeight());
+                    if (!scalingRequired || cache == null) {
+                        canvas.clipRect(0, 0, mRight - mLeft, mBottom - mTop);
+                    } else {
+                        canvas.clipRect(0, 0, cache.getWidth(), cache.getHeight());
+                    }
                 }
             }
+
+            if (mClipBounds != null) {
+                // clip bounds ignore scroll
+                canvas.clipRect(mClipBounds);
+            }
         }
 
+
+
         if (!usingRenderNodeProperties && hasDisplayList) {
             renderNode = getDisplayList();
             if (!renderNode.isValid()) {
@@ -14773,10 +14785,6 @@
      * @param canvas The Canvas to which the View is rendered.
      */
     public void draw(Canvas canvas) {
-        boolean usingRenderNodeProperties = canvas.isRecordingFor(mRenderNode);
-        if (mClipBounds != null && !usingRenderNodeProperties) {
-            canvas.clipRect(mClipBounds);
-        }
         final int privateFlags = mPrivateFlags;
         final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE &&
                 (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);
@@ -15904,16 +15912,16 @@
      * <p>
      * Subsequent calls to {@link #setBackground(Drawable)} will automatically
      * mutate the drawable and apply the specified tint and tint mode using
-     * {@link Drawable#setTint(ColorStateList, PorterDuff.Mode)}.
+     * {@link Drawable#setTintList(ColorStateList)}.
      *
      * @param tint the tint to apply, may be {@code null} to clear tint
      *
      * @attr ref android.R.styleable#View_backgroundTint
-     * @see #getBackgroundTint()
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see #getBackgroundTintList()
+     * @see Drawable#setTintList(ColorStateList)
      */
-    public void setBackgroundTint(@Nullable ColorStateList tint) {
-        mBackgroundTint = tint;
+    public void setBackgroundTintList(@Nullable ColorStateList tint) {
+        mBackgroundTintList = tint;
         mHasBackgroundTint = true;
 
         applyBackgroundTint();
@@ -15922,23 +15930,23 @@
     /**
      * @return the tint applied to the background drawable
      * @attr ref android.R.styleable#View_backgroundTint
-     * @see #setBackgroundTint(ColorStateList)
+     * @see #setBackgroundTintList(ColorStateList)
      */
     @Nullable
-    public ColorStateList getBackgroundTint() {
-        return mBackgroundTint;
+    public ColorStateList getBackgroundTintList() {
+        return mBackgroundTintList;
     }
 
     /**
      * Specifies the blending mode used to apply the tint specified by
-     * {@link #setBackgroundTint(ColorStateList)}} to the background drawable.
+     * {@link #setBackgroundTintList(ColorStateList)}} to the background drawable.
      * The default mode is {@link PorterDuff.Mode#SRC_ATOP}.
      *
      * @param tintMode the blending mode used to apply the tint, may be
      *                 {@code null} to clear tint
      * @attr ref android.R.styleable#View_backgroundTintMode
      * @see #getBackgroundTintMode()
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see Drawable#setTintMode(PorterDuff.Mode)
      */
     public void setBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
         mBackgroundTintMode = tintMode;
@@ -15959,7 +15967,8 @@
     private void applyBackgroundTint() {
         if (mBackground != null && mHasBackgroundTint) {
             mBackground = mBackground.mutate();
-            mBackground.setTint(mBackgroundTint, mBackgroundTintMode);
+            mBackground.setTintList(mBackgroundTintList);
+            mBackground.setTintMode(mBackgroundTintMode);
         }
     }
 
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index c09440b..77f4b90 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3060,24 +3060,13 @@
 
         int clipSaveCount = 0;
         final boolean clipToPadding = (flags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK;
-        boolean hasClipBounds = mClipBounds != null && !usingRenderNodeProperties;
-        boolean clippingNeeded = clipToPadding || hasClipBounds;
-
-        if (clippingNeeded) {
-            clipSaveCount = canvas.save();
-        }
-
         if (clipToPadding) {
+            clipSaveCount = canvas.save();
             canvas.clipRect(mScrollX + mPaddingLeft, mScrollY + mPaddingTop,
                     mScrollX + mRight - mLeft - mPaddingRight,
                     mScrollY + mBottom - mTop - mPaddingBottom);
         }
 
-        if (hasClipBounds) {
-            canvas.clipRect(mClipBounds.left, mClipBounds.top, mClipBounds.right,
-                    mClipBounds.bottom);
-        }
-
         // We will draw our child's animation, let's reset the flag
         mPrivateFlags &= ~PFLAG_DRAW_ANIMATION;
         mGroupFlags &= ~FLAG_INVALIDATE_REQUIRED;
@@ -3117,7 +3106,7 @@
             onDebugDraw(canvas);
         }
 
-        if (clippingNeeded) {
+        if (clipToPadding) {
             canvas.restoreToCount(clipSaveCount);
         }
 
@@ -3265,21 +3254,29 @@
             final View child = children[i];
             if (((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) &&
                     child.hasStaticLayer()) {
-                child.mRecreateDisplayList = (child.mPrivateFlags & PFLAG_INVALIDATED)
-                        == PFLAG_INVALIDATED;
-                child.mPrivateFlags &= ~PFLAG_INVALIDATED;
-                child.getDisplayList();
-                child.mRecreateDisplayList = false;
+                recreateChildDisplayList(child);
             }
         }
         if (mOverlay != null) {
             View overlayView = mOverlay.getOverlayView();
-            overlayView.mRecreateDisplayList = (overlayView.mPrivateFlags & PFLAG_INVALIDATED)
-                    == PFLAG_INVALIDATED;
-            overlayView.mPrivateFlags &= ~PFLAG_INVALIDATED;
-            overlayView.getDisplayList();
-            overlayView.mRecreateDisplayList = false;
+            recreateChildDisplayList(overlayView);
         }
+        if (mDisappearingChildren != null) {
+            final ArrayList<View> disappearingChildren = mDisappearingChildren;
+            final int disappearingCount = disappearingChildren.size();
+            for (int i = 0; i < disappearingCount; ++i) {
+                final View child = disappearingChildren.get(i);
+                recreateChildDisplayList(child);
+            }
+        }
+    }
+
+    private void recreateChildDisplayList(View child) {
+        child.mRecreateDisplayList = (child.mPrivateFlags & PFLAG_INVALIDATED)
+                == PFLAG_INVALIDATED;
+        child.mPrivateFlags &= ~PFLAG_INVALIDATED;
+        child.getDisplayList();
+        child.mRecreateDisplayList = false;
     }
 
     /**
diff --git a/core/java/android/view/ViewOutlineProvider.java b/core/java/android/view/ViewOutlineProvider.java
index 4054031..170c5d8 100644
--- a/core/java/android/view/ViewOutlineProvider.java
+++ b/core/java/android/view/ViewOutlineProvider.java
@@ -37,7 +37,6 @@
             if (background != null) {
                 background.getOutline(outline);
             } else {
-
                 outline.setRect(0, 0, view.getWidth(), view.getHeight());
                 outline.setAlpha(0.0f);
             }
@@ -51,6 +50,8 @@
      * View's size changes, or if {@link View#invalidateOutline()} is called
      * explicitly.
      *
+     * The input outline is empty and has an alpha of <code>1.0f</code>.
+     *
      * @param view The view building the outline.
      * @param outline The empty outline to be populated.
      */
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 671aa10..a326aad 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -735,15 +735,23 @@
 
     void setLayoutParams(WindowManager.LayoutParams attrs, boolean newView) {
         synchronized (this) {
-            int oldSoftInputMode = mWindowAttributes.softInputMode;
+            final int oldInsetLeft = mWindowAttributes.surfaceInsets.left;
+            final int oldInsetTop = mWindowAttributes.surfaceInsets.top;
+            final int oldInsetRight = mWindowAttributes.surfaceInsets.right;
+            final int oldInsetBottom = mWindowAttributes.surfaceInsets.bottom;
+            final int oldSoftInputMode = mWindowAttributes.softInputMode;
+
             // Keep track of the actual window flags supplied by the client.
             mClientWindowLayoutFlags = attrs.flags;
-            // preserve compatible window flag if exists.
-            int compatibleWindowFlag = mWindowAttributes.privateFlags
+
+            // Preserve compatible window flag if exists.
+            final int compatibleWindowFlag = mWindowAttributes.privateFlags
                     & WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-            // transfer over system UI visibility values as they carry current state.
+
+            // Transfer over system UI visibility values as they carry current state.
             attrs.systemUiVisibility = mWindowAttributes.systemUiVisibility;
             attrs.subtreeSystemUiVisibility = mWindowAttributes.subtreeSystemUiVisibility;
+
             mWindowAttributesChangesFlag = mWindowAttributes.copyFrom(attrs);
             if ((mWindowAttributesChangesFlag
                     & WindowManager.LayoutParams.TRANSLUCENT_FLAGS_CHANGED) != 0) {
@@ -755,20 +763,25 @@
             }
             mWindowAttributes.privateFlags |= compatibleWindowFlag;
 
+            // Restore old surface insets.
+            mWindowAttributes.surfaceInsets.set(
+                    oldInsetLeft, oldInsetTop, oldInsetRight, oldInsetBottom);
+
             applyKeepScreenOnFlag(mWindowAttributes);
 
             if (newView) {
                 mSoftInputMode = attrs.softInputMode;
                 requestLayout();
             }
+
             // Don't lose the mode we last auto-computed.
-            if ((attrs.softInputMode&WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
+            if ((attrs.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
                     == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED) {
                 mWindowAttributes.softInputMode = (mWindowAttributes.softInputMode
                         & ~WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
-                        | (oldSoftInputMode
-                                & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST);
+                        | (oldSoftInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST);
             }
+
             mWindowAttributesChanged = true;
             scheduleTraversals();
         }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 46b9e03..47ee52e 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1418,6 +1418,16 @@
         public int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 
         /**
+         * The preferred refresh rate for the window.
+         *
+         * This must be one of the supported refresh rates obtained for the display(s) the window
+         * is on.
+         *
+         * @see Display#getSupportedRefreshRates()
+         */
+        public float preferredRefreshRate;
+
+        /**
          * Control the visibility of the status bar.
          *
          * @see View#STATUS_BAR_VISIBLE
@@ -1576,6 +1586,7 @@
             out.writeString(packageName);
             TextUtils.writeToParcel(mTitle, out, parcelableFlags);
             out.writeInt(screenOrientation);
+            out.writeFloat(preferredRefreshRate);
             out.writeInt(systemUiVisibility);
             out.writeInt(subtreeSystemUiVisibility);
             out.writeInt(hasSystemUiListeners ? 1 : 0);
@@ -1622,6 +1633,7 @@
             packageName = in.readString();
             mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
             screenOrientation = in.readInt();
+            preferredRefreshRate = in.readFloat();
             systemUiVisibility = in.readInt();
             subtreeSystemUiVisibility = in.readInt();
             hasSystemUiListeners = in.readInt() != 0;
@@ -1664,6 +1676,8 @@
         /** {@hide} */
         public static final int SURFACE_INSETS_CHANGED = 1<<20;
         /** {@hide} */
+        public static final int PREFERRED_REFRESH_RATE_CHANGED = 1 << 21;
+        /** {@hide} */
         public static final int EVERYTHING_CHANGED = 0xffffffff;
 
         // internal buffer to backup/restore parameters under compatibility mode.
@@ -1776,6 +1790,11 @@
                 changes |= SCREEN_ORIENTATION_CHANGED;
             }
 
+            if (preferredRefreshRate != o.preferredRefreshRate) {
+                preferredRefreshRate = o.preferredRefreshRate;
+                changes |= PREFERRED_REFRESH_RATE_CHANGED;
+            }
+
             if (systemUiVisibility != o.systemUiVisibility
                     || subtreeSystemUiVisibility != o.subtreeSystemUiVisibility) {
                 systemUiVisibility = o.systemUiVisibility;
@@ -1884,6 +1903,10 @@
                 sb.append(" rotAnim=");
                 sb.append(rotationAnimation);
             }
+            if (preferredRefreshRate != 0) {
+                sb.append(" preferredRefreshRate=");
+                sb.append(preferredRefreshRate);
+            }
             if (systemUiVisibility != 0) {
                 sb.append(" sysui=0x");
                 sb.append(Integer.toHexString(systemUiVisibility));
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 94e2c0e..c3b17db 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -80,41 +80,14 @@
     public static final int STATE_FLAG_HIGH_TEXT_CONTRAST_ENABLED = 0x00000004;
 
     /** @hide */
-    public static final int INVERSION_DISABLED = -1;
-
-    /** @hide */
-    public static final int INVERSION_STANDARD = 0;
-
-    /** @hide */
-    public static final int INVERSION_HUE_ONLY = 1;
-
-    /** @hide */
-    public static final int INVERSION_VALUE_ONLY = 2;
-
-    /** @hide */
     public static final int DALTONIZER_DISABLED = -1;
 
     /** @hide */
     public static final int DALTONIZER_SIMULATE_MONOCHROMACY = 0;
 
     /** @hide */
-    public static final int DALTONIZER_SIMULATE_PROTANOMALY = 1;
-
-    /** @hide */
-    public static final int DALTONIZER_SIMULATE_DEUTERANOMALY = 2;
-
-    /** @hide */
-    public static final int DALTONIZER_SIMULATE_TRITANOMALY = 3;
-
-    /** @hide */
-    public static final int DALTONIZER_CORRECT_PROTANOMALY = 11;
-
-    /** @hide */
     public static final int DALTONIZER_CORRECT_DEUTERANOMALY = 12;
 
-    /** @hide */
-    public static final int DALTONIZER_CORRECT_TRITANOMALY = 13;
-
     static final Object sInstanceSync = new Object();
 
     private static AccessibilityManager sInstance;
@@ -134,16 +107,13 @@
     boolean mIsHighTextContrastEnabled;
 
     private final CopyOnWriteArrayList<AccessibilityStateChangeListener>
-            mAccessibilityStateChangeListeners = new CopyOnWriteArrayList<
-                    AccessibilityStateChangeListener>();
+            mAccessibilityStateChangeListeners = new CopyOnWriteArrayList<>();
 
     private final CopyOnWriteArrayList<TouchExplorationStateChangeListener>
-            mTouchExplorationStateChangeListeners = new CopyOnWriteArrayList<
-            TouchExplorationStateChangeListener>();
+            mTouchExplorationStateChangeListeners = new CopyOnWriteArrayList<>();
 
     private final CopyOnWriteArrayList<HighTextContrastChangeListener>
-            mHighTextContrastStateChangeListeners = new CopyOnWriteArrayList<
-            HighTextContrastChangeListener>();
+            mHighTextContrastStateChangeListeners = new CopyOnWriteArrayList<>();
 
     /**
      * Listener for the system accessibility state. To listen for changes to the
@@ -197,9 +167,13 @@
     private final IAccessibilityManagerClient.Stub mClient =
             new IAccessibilityManagerClient.Stub() {
         public void setState(int state) {
-            synchronized (mLock) {
-                setStateLocked(state);
-            }
+            // We do not want to change this immediately as the applicatoin may
+            // have already checked that accessibility is on and fired an event,
+            // that is now propagating up the view tree, Hence, if accessibility
+            // is now off an exception will be thrown. We want to have the exception
+            // enforcement to guard against apps that fire unnecessary accessibility
+            // events when accessibility is off.
+            mHandler.obtainMessage(MyHandler.MSG_SET_STATE, state, 0).sendToTarget();
         }
     };
 
@@ -393,7 +367,7 @@
     @Deprecated
     public List<ServiceInfo> getAccessibilityServiceList() {
         List<AccessibilityServiceInfo> infos = getInstalledAccessibilityServiceList();
-        List<ServiceInfo> services = new ArrayList<ServiceInfo>();
+        List<ServiceInfo> services = new ArrayList<>();
         final int infoCount = infos.size();
         for (int i = 0; i < infoCount; i++) {
             AccessibilityServiceInfo info = infos.get(i);
@@ -446,6 +420,7 @@
      * @see AccessibilityServiceInfo#FEEDBACK_HAPTIC
      * @see AccessibilityServiceInfo#FEEDBACK_SPOKEN
      * @see AccessibilityServiceInfo#FEEDBACK_VISUAL
+     * @see AccessibilityServiceInfo#FEEDBACK_BRAILLE
      */
     public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(
             int feedbackTypeFlags) {
@@ -705,6 +680,7 @@
         public static final int MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED = 1;
         public static final int MSG_NOTIFY_EXPLORATION_STATE_CHANGED = 2;
         public static final int MSG_NOTIFY_HIGH_TEXT_CONTRAST_STATE_CHANGED = 3;
+        public static final int MSG_SET_STATE = 4;
 
         public MyHandler(Looper looper) {
             super(looper, null, false);
@@ -724,6 +700,14 @@
                 case MSG_NOTIFY_HIGH_TEXT_CONTRAST_STATE_CHANGED: {
                     handleNotifyHighTextContrastStateChanged();
                 } break;
+
+                case MSG_SET_STATE: {
+                    // See comment at mClient
+                    final int state = message.arg1;
+                    synchronized (mLock) {
+                        setStateLocked(state);
+                    }
+                } break;
             }
         }
     }
diff --git a/core/java/android/webkit/CookieSyncManager.java b/core/java/android/webkit/CookieSyncManager.java
index 1c364c0..d9546ca 100644
--- a/core/java/android/webkit/CookieSyncManager.java
+++ b/core/java/android/webkit/CookieSyncManager.java
@@ -21,13 +21,6 @@
 
 
 /**
- * @deprecated The WebView now automatically syncs cookies as necessary.
- *             You no longer need to create or use the CookieSyncManager.
- *             To manually force a sync you can use the CookieManager
- *             method {@link CookieManager#flush} which is a synchronous
- *             replacement for {@link #sync}.
- *             <p>
- *
  * The CookieSyncManager is used to synchronize the browser cookie store
  * between RAM and permanent storage. To get the best performance, browser cookies are
  * saved in RAM. A separate thread saves the cookies between, driven by a timer.
@@ -61,6 +54,12 @@
  * WebViewClient#onPageFinished}. Note that even sync() happens
  * asynchronously, so don't do it just as your activity is shutting
  * down.
+ *
+ * @deprecated The WebView now automatically syncs cookies as necessary.
+ *             You no longer need to create or use the CookieSyncManager.
+ *             To manually force a sync you can use the CookieManager
+ *             method {@link CookieManager#flush} which is a synchronous
+ *             replacement for {@link #sync}.
  */
 @Deprecated
 public final class CookieSyncManager extends WebSyncManager {
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 2c7b3eb..d93ca2c 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -16,16 +16,27 @@
 
 package android.webkit;
 
+import android.app.ActivityManagerInternal;
+import android.app.Application;
+import android.app.AppGlobals;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.os.Build;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.StrictMode;
+import android.os.SystemProperties;
+import android.text.TextUtils;
 import android.util.AndroidRuntimeException;
 import android.util.Log;
+import com.android.server.LocalServices;
 import dalvik.system.VMRuntime;
 
 import java.io.File;
+import java.util.Arrays;
 
 import com.android.internal.os.Zygote;
 
@@ -42,17 +53,15 @@
     private static final String NULL_WEBVIEW_FACTORY =
             "com.android.webview.nullwebview.NullWebViewFactoryProvider";
 
-    // TODO(torne): we need to use a system property instead of hardcoding the library paths to
-    // enable it to be changed when a webview update apk is installed.
-    private static final String CHROMIUM_WEBVIEW_NATIVE_LIB_32 =
-            "/system/lib/libwebviewchromium.so";
-    private static final String CHROMIUM_WEBVIEW_NATIVE_LIB_64 =
-            "/system/lib64/libwebviewchromium.so";
     private static final String CHROMIUM_WEBVIEW_NATIVE_RELRO_32 =
             "/data/misc/shared_relro/libwebviewchromium32.relro";
     private static final String CHROMIUM_WEBVIEW_NATIVE_RELRO_64 =
             "/data/misc/shared_relro/libwebviewchromium64.relro";
 
+    public static final String CHROMIUM_WEBVIEW_VMSIZE_SIZE_PROPERTY =
+            "persist.sys.webview.vmsize";
+    private static final long CHROMIUM_WEBVIEW_DEFAULT_VMSIZE_BYTES = 100 * 1024 * 1024;
+
     private static final String LOGTAG = "WebViewFactory";
 
     private static final boolean DEBUG = false;
@@ -64,8 +73,8 @@
     private static boolean sAddressSpaceReserved = false;
 
     public static String getWebViewPackageName() {
-        // TODO: Make this dynamic based on resource configuration.
-        return "com.android.webview";
+        return AppGlobals.getInitialApplication().getString(
+                com.android.internal.R.string.config_webViewPackageName);
     }
 
     static WebViewFactoryProvider getProvider() {
@@ -99,11 +108,34 @@
     }
 
     private static Class<WebViewFactoryProvider> getFactoryClass() throws ClassNotFoundException {
+        Application initialApplication = AppGlobals.getInitialApplication();
         try {
-            return (Class<WebViewFactoryProvider>) Class.forName(CHROMIUM_WEBVIEW_FACTORY);
-        } catch (ClassNotFoundException e) {
-            Log.e(LOGTAG, "Chromium WebView does not exist");
-            return (Class<WebViewFactoryProvider>) Class.forName(NULL_WEBVIEW_FACTORY);
+            // First fetch the package info so we can log the webview package version.
+            String packageName = getWebViewPackageName();
+            PackageInfo pi = initialApplication.getPackageManager().getPackageInfo(packageName, 0);
+            Log.i(LOGTAG, "Loading " + packageName + " version " + pi.versionName +
+                          " (code " + pi.versionCode + ")");
+
+            // Construct a package context to load the Java code into the current app.
+            Context webViewContext = initialApplication.createPackageContext(packageName,
+                    Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
+            initialApplication.getAssets().addAssetPath(
+                    webViewContext.getApplicationInfo().sourceDir);
+            ClassLoader clazzLoader = webViewContext.getClassLoader();
+            return (Class<WebViewFactoryProvider>) Class.forName(CHROMIUM_WEBVIEW_FACTORY, true,
+                                                                 clazzLoader);
+        } catch (PackageManager.NameNotFoundException e) {
+            // If the package doesn't exist, then try loading the null WebView instead.
+            // If that succeeds, then this is a device without WebView support; if it fails then
+            // swallow the failure, complain that the real WebView is missing and rethrow the
+            // original exception.
+            try {
+                return (Class<WebViewFactoryProvider>) Class.forName(NULL_WEBVIEW_FACTORY);
+            } catch (ClassNotFoundException e2) {
+                // Ignore.
+            }
+            Log.e(LOGTAG, "Chromium WebView package does not exist", e);
+            throw new AndroidRuntimeException(e);
         }
     }
 
@@ -114,79 +146,197 @@
     public static void prepareWebViewInZygote() {
         try {
             System.loadLibrary("webviewchromium_loader");
-            sAddressSpaceReserved = nativeReserveAddressSpace(CHROMIUM_WEBVIEW_NATIVE_LIB_32,
-                                                              CHROMIUM_WEBVIEW_NATIVE_LIB_64);
+            long addressSpaceToReserve =
+                    SystemProperties.getLong(CHROMIUM_WEBVIEW_VMSIZE_SIZE_PROPERTY,
+                    CHROMIUM_WEBVIEW_DEFAULT_VMSIZE_BYTES);
+            sAddressSpaceReserved = nativeReserveAddressSpace(addressSpaceToReserve);
+
             if (sAddressSpaceReserved) {
-                if (DEBUG) Log.v(LOGTAG, "address space reserved");
+                if (DEBUG) {
+                    Log.v(LOGTAG, "address space reserved: " + addressSpaceToReserve + " bytes");
+                }
             } else {
-                Log.e(LOGTAG, "reserving address space failed");
+                Log.e(LOGTAG, "reserving " + addressSpaceToReserve +
+                        " bytes of address space failed");
             }
-        } catch (Throwable e) {
+        } catch (Throwable t) {
             // Log and discard errors at this stage as we must not crash the zygote.
-            Log.e(LOGTAG, "error preparing native loader", e);
+            Log.e(LOGTAG, "error preparing native loader", t);
         }
     }
 
     /**
      * Perform any WebView loading preparations that must happen at boot from the system server,
-     * after the package manager has started.
+     * after the package manager has started or after an update to the webview is installed.
      * This must be called in the system server.
      * Currently, this means spawning the child processes which will create the relro files.
      */
     public static void prepareWebViewInSystemServer() {
-        if (DEBUG) Log.v(LOGTAG, "creating relro files");
-        if (new File(CHROMIUM_WEBVIEW_NATIVE_LIB_64).exists()) {
-            createRelroFile(Build.SUPPORTED_64_BIT_ABIS[0]);
+        String[] nativePaths = null;
+        try {
+            nativePaths = getWebViewNativeLibraryPaths();
+        } catch (PackageManager.NameNotFoundException e) {
         }
-        if (new File(CHROMIUM_WEBVIEW_NATIVE_LIB_32).exists()) {
-            createRelroFile(Build.SUPPORTED_32_BIT_ABIS[0]);
+        prepareWebViewInSystemServer(nativePaths);
+    }
+
+    private static void prepareWebViewInSystemServer(String[] nativeLibraryPaths) {
+        if (DEBUG) Log.v(LOGTAG, "creating relro files");
+
+        // We must always trigger createRelRo regardless of the value of nativeLibraryPaths. Any
+        // unexpected values will be handled there to ensure that we trigger notifying any process
+        // waiting on relreo creation.
+        if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
+            if (DEBUG) Log.v(LOGTAG, "Create 32 bit relro");
+            createRelroFile(false /* is64Bit */, nativeLibraryPaths);
+        }
+
+        if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
+            if (DEBUG) Log.v(LOGTAG, "Create 64 bit relro");
+            createRelroFile(true /* is64Bit */, nativeLibraryPaths);
         }
     }
 
-    private static void createRelroFile(String abi) {
+    public static void onWebViewUpdateInstalled() {
+        String[] nativeLibs = null;
         try {
-            Process.start("android.webkit.WebViewFactory$RelroFileCreator",
-                          "WebViewLoader-" + abi,
-                          Process.SHARED_RELRO_UID,
-                          Process.SHARED_RELRO_UID,
-                          null,
-                          0,                 // TODO(torne): do we need to set debug flags?
-                          Zygote.MOUNT_EXTERNAL_NONE,
-                          Build.VERSION.SDK_INT,
-                          null,
-                          abi,
-                          null);
-        } catch (Throwable e) {
+            nativeLibs = WebViewFactory.getWebViewNativeLibraryPaths();
+        } catch (PackageManager.NameNotFoundException e) {
+        }
+
+        if (nativeLibs != null) {
+            long newVmSize = 0L;
+
+            for (String path : nativeLibs) {
+                if (DEBUG) Log.d(LOGTAG, "Checking file size of " + path);
+                if (path == null) continue;
+                File f = new File(path);
+                if (f.exists()) {
+                    long length = f.length();
+                    if (length > newVmSize) {
+                        newVmSize = length;
+                    }
+                }
+            }
+
+            if (DEBUG) {
+                Log.v(LOGTAG, "Based on library size, need " + newVmSize +
+                        " bytes of address space.");
+            }
+            // The required memory can be larger than the file on disk (due to .bss), and an
+            // upgraded version of the library will likely be larger, so always attempt to reserve
+            // twice as much as we think to allow for the library to grow during this boot cycle.
+            newVmSize = Math.max(2 * newVmSize, CHROMIUM_WEBVIEW_DEFAULT_VMSIZE_BYTES);
+            Log.d(LOGTAG, "Setting new address space to " + newVmSize);
+            SystemProperties.set(CHROMIUM_WEBVIEW_VMSIZE_SIZE_PROPERTY,
+                    Long.toString(newVmSize));
+        }
+        prepareWebViewInSystemServer(nativeLibs);
+    }
+
+    private static String[] getWebViewNativeLibraryPaths()
+            throws PackageManager.NameNotFoundException {
+        final String NATIVE_LIB_FILE_NAME = "libwebviewchromium.so";
+
+        PackageManager pm = AppGlobals.getInitialApplication().getPackageManager();
+        ApplicationInfo ai = pm.getApplicationInfo(getWebViewPackageName(), 0);
+
+        String path32;
+        String path64;
+        boolean primaryArchIs64bit = VMRuntime.is64BitAbi(ai.primaryCpuAbi);
+        if (!TextUtils.isEmpty(ai.secondaryCpuAbi)) {
+            // Multi-arch case.
+            if (primaryArchIs64bit) {
+                // Primary arch: 64-bit, secondary: 32-bit.
+                path64 = ai.nativeLibraryDir;
+                path32 = ai.secondaryNativeLibraryDir;
+            } else {
+                // Primary arch: 32-bit, secondary: 64-bit.
+                path64 = ai.secondaryNativeLibraryDir;
+                path32 = ai.nativeLibraryDir;
+            }
+        } else if (primaryArchIs64bit) {
+            // Single-arch 64-bit.
+            path64 = ai.nativeLibraryDir;
+            path32 = "";
+        } else {
+            // Single-arch 32-bit.
+            path32 = ai.nativeLibraryDir;
+            path64 = "";
+        }
+        if (!TextUtils.isEmpty(path32)) path32 += "/" + NATIVE_LIB_FILE_NAME;
+        if (!TextUtils.isEmpty(path64)) path64 += "/" + NATIVE_LIB_FILE_NAME;
+        return new String[] { path32, path64 };
+    }
+
+    private static void createRelroFile(final boolean is64Bit, String[] nativeLibraryPaths) {
+        final String abi =
+                is64Bit ? Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
+
+        // crashHandler is invoked by the ActivityManagerService when the isolated process crashes.
+        Runnable crashHandler = new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    Log.e(LOGTAG, "relro file creator for " + abi + " crashed. Proceeding without");
+                    getUpdateService().notifyRelroCreationCompleted(is64Bit, false);
+                } catch (RemoteException e) {
+                    Log.e(LOGTAG, "Cannot reach WebViewUpdateService. " + e.getMessage());
+                }
+            }
+        };
+
+        try {
+            if (nativeLibraryPaths == null
+                    || nativeLibraryPaths[0] == null || nativeLibraryPaths[1] == null) {
+                throw new IllegalArgumentException(
+                        "Native library paths to the WebView RelRo process must not be null!");
+            }
+            int pid = LocalServices.getService(ActivityManagerInternal.class).startIsolatedProcess(
+                    RelroFileCreator.class.getName(), nativeLibraryPaths, "WebViewLoader-" + abi, abi,
+                    Process.SHARED_RELRO_UID, crashHandler);
+            if (pid <= 0) throw new Exception("Failed to start the relro file creator process");
+        } catch (Throwable t) {
             // Log and discard errors as we must not crash the system server.
-            Log.e(LOGTAG, "error starting relro file creator for abi " + abi, e);
+            Log.e(LOGTAG, "error starting relro file creator for abi " + abi, t);
+            crashHandler.run();
         }
     }
 
     private static class RelroFileCreator {
         // Called in an unprivileged child process to create the relro file.
         public static void main(String[] args) {
-            if (!sAddressSpaceReserved) {
-                Log.e(LOGTAG, "can't create relro file; address space not reserved");
-                return;
-            }
-            boolean result = nativeCreateRelroFile(CHROMIUM_WEBVIEW_NATIVE_LIB_32,
-                                                   CHROMIUM_WEBVIEW_NATIVE_LIB_64,
-                                                   CHROMIUM_WEBVIEW_NATIVE_RELRO_32,
-                                                   CHROMIUM_WEBVIEW_NATIVE_RELRO_64);
-            if (!result) {
-                Log.e(LOGTAG, "failed to create relro file");
-            } else if (DEBUG) {
-                Log.v(LOGTAG, "created relro file");
-            }
-            try {
-                getUpdateService().notifyRelroCreationCompleted(VMRuntime.getRuntime().is64Bit(),
-                                                                result);
-            } catch (RemoteException e) {
-                Log.e(LOGTAG, "error notifying update service", e);
-            }
+            boolean result = false;
+            boolean is64Bit = VMRuntime.getRuntime().is64Bit();
+            try{
+                if (args.length != 2 || args[0] == null || args[1] == null) {
+                    Log.e(LOGTAG, "Invalid RelroFileCreator args: " + Arrays.toString(args));
+                    return;
+                }
+                Log.v(LOGTAG, "RelroFileCreator (64bit = " + is64Bit + "), " +
+                        " 32-bit lib: " + args[0] + ", 64-bit lib: " + args[1]);
+                if (!sAddressSpaceReserved) {
+                    Log.e(LOGTAG, "can't create relro file; address space not reserved");
+                    return;
+                }
+                result = nativeCreateRelroFile(args[0] /* path32 */,
+                                               args[1] /* path64 */,
+                                               CHROMIUM_WEBVIEW_NATIVE_RELRO_32,
+                                               CHROMIUM_WEBVIEW_NATIVE_RELRO_64);
+                if (result && DEBUG) Log.v(LOGTAG, "created relro file");
+            } finally {
+                // We must do our best to always notify the update service, even if something fails.
+                try {
+                    getUpdateService().notifyRelroCreationCompleted(is64Bit, result);
+                } catch (RemoteException e) {
+                    Log.e(LOGTAG, "error notifying update service", e);
+                }
 
-            // Must explicitly exit or else this process will just sit around after we return.
-            System.exit(0);
+                if (!result) Log.e(LOGTAG, "failed to create relro file");
+
+                // Must explicitly exit or else this process will just sit around after we return.
+                System.exit(0);
+            }
         }
     }
 
@@ -203,14 +353,19 @@
             return;
         }
 
-        boolean result = nativeLoadWithRelroFile(CHROMIUM_WEBVIEW_NATIVE_LIB_32,
-                                                 CHROMIUM_WEBVIEW_NATIVE_LIB_64,
-                                                 CHROMIUM_WEBVIEW_NATIVE_RELRO_32,
-                                                 CHROMIUM_WEBVIEW_NATIVE_RELRO_64);
-        if (!result) {
-            Log.w(LOGTAG, "failed to load with relro file, proceeding without");
-        } else if (DEBUG) {
-            Log.v(LOGTAG, "loaded with relro file");
+        try {
+            String[] args = getWebViewNativeLibraryPaths();
+            boolean result = nativeLoadWithRelroFile(args[0] /* path32 */,
+                                                     args[1] /* path64 */,
+                                                     CHROMIUM_WEBVIEW_NATIVE_RELRO_32,
+                                                     CHROMIUM_WEBVIEW_NATIVE_RELRO_64);
+            if (!result) {
+                Log.w(LOGTAG, "failed to load with relro file, proceeding without");
+            } else if (DEBUG) {
+                Log.v(LOGTAG, "loaded with relro file");
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.e(LOGTAG, "Failed to list WebView package libraries for loadNativeLibrary", e);
         }
     }
 
@@ -218,7 +373,7 @@
         return IWebViewUpdateService.Stub.asInterface(ServiceManager.getService("webviewupdate"));
     }
 
-    private static native boolean nativeReserveAddressSpace(String lib32, String lib64);
+    private static native boolean nativeReserveAddressSpace(long addressSpaceToReserve);
     private static native boolean nativeCreateRelroFile(String lib32, String lib64,
                                                         String relro32, String relro64);
     private static native boolean nativeLoadWithRelroFile(String lib32, String lib64,
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 2708525..39cd7e3 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -41,7 +41,7 @@
     private final Rect mTempRect = new Rect();
 
     private Drawable mThumb;
-    private ColorStateList mThumbTint = null;
+    private ColorStateList mThumbTintList = null;
     private PorterDuff.Mode mThumbTintMode = PorterDuff.Mode.SRC_ATOP;
     private boolean mHasThumbTint = false;
 
@@ -100,7 +100,7 @@
                 R.styleable.SeekBar_thumbTintMode, -1), mThumbTintMode);
 
         if (a.hasValue(R.styleable.SeekBar_thumbTint)) {
-            mThumbTint = a.getColorStateList(R.styleable.SeekBar_thumbTint);
+            mThumbTintList = a.getColorStateList(R.styleable.SeekBar_thumbTint);
             mHasThumbTint = true;
 
             applyThumbTint();
@@ -193,16 +193,16 @@
      * <p>
      * Subsequent calls to {@link #setThumb(Drawable)} will automatically
      * mutate the drawable and apply the specified tint and tint mode using
-     * {@link Drawable#setTint(ColorStateList, PorterDuff.Mode)}.
+     * {@link Drawable#setTintList(ColorStateList)}.
      *
      * @param tint the tint to apply, may be {@code null} to clear tint
      *
      * @attr ref android.R.styleable#SeekBar_thumbTint
-     * @see #getThumbTint()
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see #getThumbTintList()
+     * @see Drawable#setTintList(ColorStateList)
      */
-    public void setThumbTint(@Nullable ColorStateList tint) {
-        mThumbTint = tint;
+    public void setThumbTintList(@Nullable ColorStateList tint) {
+        mThumbTintList = tint;
         mHasThumbTint = true;
 
         applyThumbTint();
@@ -211,16 +211,16 @@
     /**
      * @return the tint applied to the thumb drawable
      * @attr ref android.R.styleable#SeekBar_thumbTint
-     * @see #setThumbTint(ColorStateList)
+     * @see #setThumbTintList(ColorStateList)
      */
     @Nullable
-    public ColorStateList getThumbTint() {
-        return mThumbTint;
+    public ColorStateList getThumbTintList() {
+        return mThumbTintList;
     }
 
     /**
      * Specifies the blending mode used to apply the tint specified by
-     * {@link #setThumbTint(ColorStateList)}} to the thumb drawable. The
+     * {@link #setThumbTintList(ColorStateList)}} to the thumb drawable. The
      * default mode is {@link PorterDuff.Mode#SRC_ATOP}.
      *
      * @param tintMode the blending mode used to apply the tint, may be
@@ -228,7 +228,7 @@
      *
      * @attr ref android.R.styleable#SeekBar_thumbTintMode
      * @see #getThumbTintMode()
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see Drawable#setTintMode(PorterDuff.Mode)
      */
     public void setThumbTintMode(@Nullable PorterDuff.Mode tintMode) {
         mThumbTintMode = tintMode;
@@ -249,7 +249,8 @@
     private void applyThumbTint() {
         if (mThumb != null && mHasThumbTint) {
             mThumb = mThumb.mutate();
-            mThumb.setTint(mThumbTint, mThumbTintMode);
+            mThumb.setTintList(mThumbTintList);
+            mThumb.setTintMode(mThumbTintMode);
         }
     }
 
diff --git a/core/java/android/widget/AdapterViewFlipper.java b/core/java/android/widget/AdapterViewFlipper.java
index 3b026bd..285dee8 100644
--- a/core/java/android/widget/AdapterViewFlipper.java
+++ b/core/java/android/widget/AdapterViewFlipper.java
@@ -105,7 +105,17 @@
         final IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_SCREEN_OFF);
         filter.addAction(Intent.ACTION_USER_PRESENT);
-        getContext().registerReceiver(mReceiver, filter);
+
+        // OK, this is gross but needed. This class is supported by the
+        // remote views machanism and as a part of that the remote views
+        // can be inflated by a context for another user without the app
+        // having interact users permission - just for loading resources.
+        // For exmaple, when adding widgets from a user profile to the
+        // home screen. Therefore, we register the receiver as the current
+        // user not the one the context is for.
+        getContext().registerReceiverAsUser(mReceiver, android.os.Process.myUserHandle(),
+                filter, null, mHandler);
+
 
         if (mAutoStart) {
             // Automatically start when requested
diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java
index 5b80648..1716dbd 100644
--- a/core/java/android/widget/AnalogClock.java
+++ b/core/java/android/widget/AnalogClock.java
@@ -111,7 +111,15 @@
             filter.addAction(Intent.ACTION_TIME_CHANGED);
             filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
 
-            getContext().registerReceiver(mIntentReceiver, filter, null, mHandler);
+            // OK, this is gross but needed. This class is supported by the
+            // remote views machanism and as a part of that the remote views
+            // can be inflated by a context for another user without the app
+            // having interact users permission - just for loading resources.
+            // For exmaple, when adding widgets from a user profile to the
+            // home screen. Therefore, we register the receiver as the current
+            // user not the one the context is for.
+            getContext().registerReceiverAsUser(mIntentReceiver,
+                    android.os.Process.myUserHandle(), filter, null, mHandler);
         }
 
         // NOTE: It's safe to do these after registering the receiver since the receiver always runs
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index 791151c..ccd0480 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -47,7 +47,7 @@
 
     private int mCheckMarkResource;
     private Drawable mCheckMarkDrawable;
-    private ColorStateList mCheckMarkTint = null;
+    private ColorStateList mCheckMarkTintList = null;
     private PorterDuff.Mode mCheckMarkTintMode = PorterDuff.Mode.SRC_ATOP;
     private boolean mHasCheckMarkTint = false;
 
@@ -86,7 +86,7 @@
                 R.styleable.CompoundButton_buttonTintMode, -1), mCheckMarkTintMode);
 
         if (a.hasValue(R.styleable.CompoundButton_buttonTint)) {
-            mCheckMarkTint = a.getColorStateList(R.styleable.CompoundButton_buttonTint);
+            mCheckMarkTintList = a.getColorStateList(R.styleable.CompoundButton_buttonTint);
             mHasCheckMarkTint = true;
 
             applyCheckMarkTint();
@@ -189,16 +189,16 @@
      * Subsequent calls to {@link #setCheckMarkDrawable(Drawable)} will
      * automatically mutate the drawable and apply the specified tint and
      * tint mode using
-     * {@link Drawable#setTint(ColorStateList, PorterDuff.Mode)}.
+     * {@link Drawable#setTintList(ColorStateList)}.
      *
      * @param tint the tint to apply, may be {@code null} to clear tint
      *
      * @attr ref android.R.styleable#CheckedTextView_checkMarkTint
-     * @see #getCheckMarkTint()
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see #getCheckMarkTintList()
+     * @see Drawable#setTintList(ColorStateList)
      */
-    public void setCheckMarkTint(@Nullable ColorStateList tint) {
-        mCheckMarkTint = tint;
+    public void setCheckMarkTintList(@Nullable ColorStateList tint) {
+        mCheckMarkTintList = tint;
         mHasCheckMarkTint = true;
 
         applyCheckMarkTint();
@@ -207,23 +207,23 @@
     /**
      * @return the tint applied to the check mark drawable
      * @attr ref android.R.styleable#CheckedTextView_checkMarkTint
-     * @see #setCheckMarkTint(ColorStateList)
+     * @see #setCheckMarkTintList(ColorStateList)
      */
     @Nullable
-    public ColorStateList getCheckMarkTint() {
-        return mCheckMarkTint;
+    public ColorStateList getCheckMarkTintList() {
+        return mCheckMarkTintList;
     }
 
     /**
      * Specifies the blending mode used to apply the tint specified by
-     * {@link #setCheckMarkTint(ColorStateList)} to the check mark
+     * {@link #setCheckMarkTintList(ColorStateList)} to the check mark
      * drawable. The default mode is {@link PorterDuff.Mode#SRC_ATOP}.
      *
      * @param tintMode the blending mode used to apply the tint, may be
      *                 {@code null} to clear tint
      * @attr ref android.R.styleable#CheckedTextView_checkMarkTintMode
-     * @see #setCheckMarkTint(ColorStateList)
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see #setCheckMarkTintList(ColorStateList)
+     * @see Drawable#setTintMode(PorterDuff.Mode)
      */
     public void setCheckMarkTintMode(@Nullable PorterDuff.Mode tintMode) {
         mCheckMarkTintMode = tintMode;
@@ -244,7 +244,8 @@
     private void applyCheckMarkTint() {
         if (mCheckMarkDrawable != null && mHasCheckMarkTint) {
             mCheckMarkDrawable = mCheckMarkDrawable.mutate();
-            mCheckMarkDrawable.setTint(mCheckMarkTint, mCheckMarkTintMode);
+            mCheckMarkDrawable.setTintList(mCheckMarkTintList);
+            mCheckMarkDrawable.setTintMode(mCheckMarkTintMode);
         }
     }
 
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index a45777e..c1d8cb3 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -53,7 +53,7 @@
     private boolean mBroadcasting;
 
     private Drawable mButtonDrawable;
-    private ColorStateList mButtonTint = null;
+    private ColorStateList mButtonTintList = null;
     private PorterDuff.Mode mButtonTintMode = PorterDuff.Mode.SRC_ATOP;
     private boolean mHasButtonTint = false;
 
@@ -91,7 +91,7 @@
                 R.styleable.CompoundButton_buttonTintMode, -1), mButtonTintMode);
 
         if (a.hasValue(R.styleable.CompoundButton_buttonTint)) {
-            mButtonTint = a.getColorStateList(R.styleable.CompoundButton_buttonTint);
+            mButtonTintList = a.getColorStateList(R.styleable.CompoundButton_buttonTint);
             mHasButtonTint = true;
 
             applyButtonTint();
@@ -245,16 +245,16 @@
      * Subsequent calls to {@link #setButtonDrawable(Drawable)} will
      * automatically mutate the drawable and apply the specified tint and tint
      * mode using
-     * {@link Drawable#setTint(ColorStateList, PorterDuff.Mode)}.
+     * {@link Drawable#setTintList(ColorStateList)}.
      *
      * @param tint the tint to apply, may be {@code null} to clear tint
      *
      * @attr ref android.R.styleable#CompoundButton_buttonTint
-     * @see #setButtonTint(ColorStateList)
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see #setButtonTintList(ColorStateList)
+     * @see Drawable#setTintList(ColorStateList)
      */
-    public void setButtonTint(@Nullable ColorStateList tint) {
-        mButtonTint = tint;
+    public void setButtonTintList(@Nullable ColorStateList tint) {
+        mButtonTintList = tint;
         mHasButtonTint = true;
 
         applyButtonTint();
@@ -263,23 +263,23 @@
     /**
      * @return the tint applied to the button drawable
      * @attr ref android.R.styleable#CompoundButton_buttonTint
-     * @see #setButtonTint(ColorStateList)
+     * @see #setButtonTintList(ColorStateList)
      */
     @Nullable
-    public ColorStateList getButtonTint() {
-        return mButtonTint;
+    public ColorStateList getButtonTintList() {
+        return mButtonTintList;
     }
 
     /**
      * Specifies the blending mode used to apply the tint specified by
-     * {@link #setButtonTint(ColorStateList)}} to the button drawable. The
+     * {@link #setButtonTintList(ColorStateList)}} to the button drawable. The
      * default mode is {@link PorterDuff.Mode#SRC_ATOP}.
      *
      * @param tintMode the blending mode used to apply the tint, may be
      *                 {@code null} to clear tint
      * @attr ref android.R.styleable#CompoundButton_buttonTintMode
      * @see #getButtonTintMode()
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see Drawable#setTintMode(PorterDuff.Mode)
      */
     public void setButtonTintMode(@Nullable PorterDuff.Mode tintMode) {
         mButtonTintMode = tintMode;
@@ -300,7 +300,8 @@
     private void applyButtonTint() {
         if (mButtonDrawable != null && mHasButtonTint) {
             mButtonDrawable = mButtonDrawable.mutate();
-            mButtonDrawable.setTint(mButtonTint, mButtonTintMode);
+            mButtonDrawable.setTintList(mButtonTintList);
+            mButtonDrawable.setTintMode(mButtonTintMode);
         }
     }
 
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 66c4b81..58f9801 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -19,6 +19,7 @@
 import android.content.UndoManager;
 import android.content.UndoOperation;
 import android.content.UndoOwner;
+import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.InputFilter;
@@ -26,6 +27,7 @@
 
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.GrowingArrayUtils;
+import com.android.internal.view.menu.MenuBuilder;
 import com.android.internal.widget.EditableInputConnection;
 
 import android.R;
@@ -2810,7 +2812,12 @@
 
         @Override
         public boolean onCreateActionMode(ActionMode mode, Menu menu) {
-            TypedArray styledAttributes = mTextView.getContext().obtainStyledAttributes(
+            final boolean legacy = mTextView.getContext().getApplicationInfo().targetSdkVersion <
+                    Build.VERSION_CODES.L;
+            final Context context = !legacy && menu instanceof MenuBuilder ?
+                    ((MenuBuilder) menu).getContext() :
+                    mTextView.getContext();
+            final TypedArray styledAttributes = context.obtainStyledAttributes(
                     com.android.internal.R.styleable.SelectionModeDrawables);
 
             mode.setTitle(mTextView.getContext().getString(
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 81dfcbb..4fb7e62 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -67,7 +67,7 @@
 
     @ViewDebug.ExportedProperty(category = "drawing")
     private Drawable mForeground;
-    private ColorStateList mForegroundTint = null;
+    private ColorStateList mForegroundTintList = null;
     private PorterDuff.Mode mForegroundTintMode = PorterDuff.Mode.SRC_ATOP;
     private boolean mHasForegroundTint = false;
 
@@ -131,7 +131,7 @@
                 R.styleable.FrameLayout_foregroundTintMode, -1), mForegroundTintMode);
 
         if (a.hasValue(R.styleable.FrameLayout_foregroundTint)) {
-            mForegroundTint = a.getColorStateList(R.styleable.FrameLayout_foregroundTint);
+            mForegroundTintList = a.getColorStateList(R.styleable.FrameLayout_foregroundTint);
             mHasForegroundTint = true;
 
             applyForegroundTint();
@@ -301,40 +301,21 @@
     }
 
     /**
-     * Applies a tint to the foreground drawable.
-     * <p>
-     * Subsequent calls to {@link #setForeground(Drawable)} will automatically
-     * mutate the drawable and apply the specified tint and tint mode using
-     * {@link Drawable#setTint(ColorStateList, PorterDuff.Mode)}.
-     *
-     * @param tint the tint to apply, may be {@code null} to clear tint
-     * @param tintMode the blending mode used to apply the tint, may be
-     *                 {@code null} to clear tint
-     *
-     * @attr ref android.R.styleable#FrameLayout_foregroundTint
-     * @attr ref android.R.styleable#FrameLayout_foregroundTintMode
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
-     */
-    private void setForegroundTint(@Nullable ColorStateList tint,
-            @Nullable PorterDuff.Mode tintMode) {
-    }
-
-    /**
      * Applies a tint to the foreground drawable. Does not modify the current
      * tint mode, which is {@link PorterDuff.Mode#SRC_ATOP} by default.
      * <p>
      * Subsequent calls to {@link #setForeground(Drawable)} will automatically
      * mutate the drawable and apply the specified tint and tint mode using
-     * {@link Drawable#setTint(ColorStateList, PorterDuff.Mode)}.
+     * {@link Drawable#setTintList(ColorStateList)}.
      *
      * @param tint the tint to apply, may be {@code null} to clear tint
      *
      * @attr ref android.R.styleable#FrameLayout_foregroundTint
-     * @see #getForegroundTint()
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see #getForegroundTintList()
+     * @see Drawable#setTintList(ColorStateList)
      */
-    public void setForegroundTint(@Nullable ColorStateList tint) {
-        mForegroundTint = tint;
+    public void setForegroundTintList(@Nullable ColorStateList tint) {
+        mForegroundTintList = tint;
         mHasForegroundTint = true;
 
         applyForegroundTint();
@@ -343,23 +324,23 @@
     /**
      * @return the tint applied to the foreground drawable
      * @attr ref android.R.styleable#FrameLayout_foregroundTint
-     * @see #setForegroundTint(ColorStateList)
+     * @see #setForegroundTintList(ColorStateList)
      */
     @Nullable
-    public ColorStateList getForegroundTint() {
-        return mForegroundTint;
+    public ColorStateList getForegroundTintList() {
+        return mForegroundTintList;
     }
 
     /**
      * Specifies the blending mode used to apply the tint specified by
-     * {@link #setForegroundTint(ColorStateList)}} to the foreground drawable.
+     * {@link #setForegroundTintList(ColorStateList)}} to the foreground drawable.
      * The default mode is {@link PorterDuff.Mode#SRC_ATOP}.
      *
      * @param tintMode the blending mode used to apply the tint, may be
      *                 {@code null} to clear tint
      * @attr ref android.R.styleable#FrameLayout_foregroundTintMode
      * @see #getForegroundTintMode()
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see Drawable#setTintMode(PorterDuff.Mode)
      */
     public void setForegroundTintMode(@Nullable PorterDuff.Mode tintMode) {
         mForegroundTintMode = tintMode;
@@ -381,7 +362,8 @@
     private void applyForegroundTint() {
         if (mForeground != null && mHasForegroundTint) {
             mForeground = mForeground.mutate();
-            mForeground.setTint(mForegroundTint, mForegroundTintMode);
+            mForeground.setTintList(mForegroundTintList);
+            mForeground.setTintMode(mForegroundTintMode);
         }
     }
 
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 0881f3e..6a15078 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -175,7 +175,7 @@
             mDrawableTint = a.getColorStateList(R.styleable.ImageView_tint);
             mHasDrawableTint = true;
 
-            applyDrawableTint();
+            applyImageTint();
         }
 
         final int alpha = a.getInt(com.android.internal.R.styleable.ImageView_drawableAlpha, 255);
@@ -454,62 +454,63 @@
      * <p>
      * Subsequent calls to {@link #setImageDrawable(Drawable)} will automatically
      * mutate the drawable and apply the specified tint and tint mode using
-     * {@link Drawable#setTint(ColorStateList, PorterDuff.Mode)}.
+     * {@link Drawable#setTintList(ColorStateList)}.
      *
      * @param tint the tint to apply, may be {@code null} to clear tint
      *
      * @attr ref android.R.styleable#ImageView_tint
-     * @see #getTint()
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see #getImageTintList()
+     * @see Drawable#setTintList(ColorStateList)
      */
-    public void setTint(@Nullable ColorStateList tint) {
+    public void setImageTintList(@Nullable ColorStateList tint) {
         mDrawableTint = tint;
         mHasDrawableTint = true;
 
-        applyDrawableTint();
+        applyImageTint();
     }
 
     /**
      * @return the tint applied to the image drawable
      * @attr ref android.R.styleable#ImageView_tint
-     * @see #setTint(ColorStateList)
+     * @see #setImageTintList(ColorStateList)
      */
     @Nullable
-    public ColorStateList getTint() {
+    public ColorStateList getImageTintList() {
         return mDrawableTint;
     }
 
     /**
      * Specifies the blending mode used to apply the tint specified by
-     * {@link #setTint(ColorStateList)}} to the image drawable. The default
+     * {@link #setImageTintList(ColorStateList)}} to the image drawable. The default
      * mode is {@link PorterDuff.Mode#SRC_ATOP}.
      *
      * @param tintMode the blending mode used to apply the tint, may be
      *                 {@code null} to clear tint
      * @attr ref android.R.styleable#ImageView_tintMode
-     * @see #getTintMode()
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see #getImageTintMode()
+     * @see Drawable#setTintMode(PorterDuff.Mode)
      */
-    public void setTintMode(@Nullable PorterDuff.Mode tintMode) {
+    public void setImageTintMode(@Nullable PorterDuff.Mode tintMode) {
         mDrawableTintMode = tintMode;
 
-        applyDrawableTint();
+        applyImageTint();
     }
 
     /**
      * @return the blending mode used to apply the tint to the image drawable
      * @attr ref android.R.styleable#ImageView_tintMode
-     * @see #setTintMode(PorterDuff.Mode)
+     * @see #setImageTintMode(PorterDuff.Mode)
      */
     @Nullable
-    public PorterDuff.Mode getTintMode() {
+    public PorterDuff.Mode getImageTintMode() {
         return mDrawableTintMode;
     }
 
-    private void applyDrawableTint() {
+    private void applyImageTint() {
         if (mDrawable != null && mHasDrawableTint) {
             mDrawable = mDrawable.mutate();
-            mDrawable.setTint(mDrawableTint, mDrawableTintMode);
+            mDrawable.setTintList(mDrawableTint);
+            mDrawable.setTintMode(mDrawableTintMode);
         }
     }
 
@@ -801,7 +802,7 @@
             d.setLevel(mLevel);
             mDrawableWidth = d.getIntrinsicWidth();
             mDrawableHeight = d.getIntrinsicHeight();
-            applyDrawableTint();
+            applyImageTint();
             applyColorMod();
             configureBounds();
         } else {
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index af4644b..6a514ba 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -270,7 +270,7 @@
      * @param modal {@code true} if the popup window should be modal, {@code false} otherwise.
      */
     public void setModal(boolean modal) {
-        mModal = true;
+        mModal = modal;
         mPopup.setFocusable(modal);
     }
 
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 4a30809..c0fa6e5 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -216,21 +216,21 @@
     private boolean mHasAnimation;
 
     private Drawable mIndeterminateDrawable;
-    private ColorStateList mIndeterminateTint = null;
+    private ColorStateList mIndeterminateTintList = null;
     private PorterDuff.Mode mIndeterminateTintMode = PorterDuff.Mode.SRC_ATOP;
     private boolean mHasIndeterminateTint = false;
 
     private Drawable mProgressDrawable;
 
-    private ColorStateList mProgressTint = null;
+    private ColorStateList mProgressTintList = null;
     private PorterDuff.Mode mProgressTintMode = PorterDuff.Mode.SRC_ATOP;
     private boolean mHasProgressTint = false;
 
-    private ColorStateList mProgressBackgroundTint = null;
+    private ColorStateList mProgressBackgroundTintList = null;
     private PorterDuff.Mode mProgressBackgroundTintMode = PorterDuff.Mode.SRC_ATOP;
     private boolean mHasProgressBackgroundTint = false;
 
-    private ColorStateList mSecondaryProgressTint = null;
+    private ColorStateList mSecondaryProgressTintList = null;
     private PorterDuff.Mode mSecondaryProgressTintMode = PorterDuff.Mode.SRC_ATOP;
     private boolean mHasSecondaryProgressTint = false;
 
@@ -332,11 +332,11 @@
                 R.styleable.ProgressBar_progressBackgroundTintMode, -1), mProgressTintMode);
 
         if (a.hasValue(R.styleable.ProgressBar_progressTint)) {
-            mProgressTint = a.getColorStateList(
+            mProgressTintList = a.getColorStateList(
                     R.styleable.ProgressBar_progressTint);
             mHasProgressTint = true;
 
-            applyProgressLayerTint(R.id.progress, mProgressTint,
+            applyProgressLayerTint(R.id.progress, mProgressTintList,
                     mProgressTintMode, true);
         }
 
@@ -344,11 +344,11 @@
                 R.styleable.ProgressBar_progressTintMode, -1), mProgressBackgroundTintMode);
 
         if (a.hasValue(R.styleable.ProgressBar_progressBackgroundTint)) {
-            mProgressBackgroundTint = a.getColorStateList(
+            mProgressBackgroundTintList = a.getColorStateList(
                     R.styleable.ProgressBar_progressBackgroundTint);
             mHasProgressBackgroundTint = true;
 
-            applyProgressLayerTint(R.id.background, mProgressBackgroundTint,
+            applyProgressLayerTint(R.id.background, mProgressBackgroundTintList,
                     mProgressBackgroundTintMode, false);
         }
 
@@ -356,11 +356,11 @@
                 R.styleable.ProgressBar_secondaryProgressTintMode, -1), mSecondaryProgressTintMode);
 
         if (a.hasValue(R.styleable.ProgressBar_secondaryProgressTint)) {
-            mSecondaryProgressTint = a.getColorStateList(
+            mSecondaryProgressTintList = a.getColorStateList(
                     R.styleable.ProgressBar_secondaryProgressTint);
             mHasSecondaryProgressTint = true;
 
-            applyProgressLayerTint(R.id.secondaryProgress, mSecondaryProgressTint,
+            applyProgressLayerTint(R.id.secondaryProgress, mSecondaryProgressTintList,
                     mSecondaryProgressTintMode, false);
         }
 
@@ -368,7 +368,7 @@
                 R.styleable.ProgressBar_indeterminateTintMode, -1), mIndeterminateTintMode);
 
         if (a.hasValue(R.styleable.ProgressBar_indeterminateTint)) {
-            mIndeterminateTint = a.getColorStateList(
+            mIndeterminateTintList = a.getColorStateList(
                     R.styleable.ProgressBar_indeterminateTint);
             mHasIndeterminateTint = true;
 
@@ -430,7 +430,8 @@
             shapeDrawable.getPaint().setShader(bitmapShader);
 
             // Ensure the tint and filter are propagated in the correct order.
-            shapeDrawable.setTint(bitmap.getTint(), bitmap.getTintMode());
+            shapeDrawable.setTintList(bitmap.getTint());
+            shapeDrawable.setTintMode(bitmap.getTintMode());
             shapeDrawable.setColorFilter(bitmap.getColorFilter());
 
             return clip ? new ClipDrawable(
@@ -582,16 +583,16 @@
      * Subsequent calls to {@link #setIndeterminateDrawable(Drawable)} will
      * automatically mutate the drawable and apply the specified tint and
      * tint mode using
-     * {@link Drawable#setTint(ColorStateList, android.graphics.PorterDuff.Mode)}.
+     * {@link Drawable#setTintList(ColorStateList)}.
      *
      * @param tint the tint to apply, may be {@code null} to clear tint
      *
      * @attr ref android.R.styleable#ProgressBar_indeterminateTint
-     * @see #getIndeterminateTint()
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see #getIndeterminateTintList()
+     * @see Drawable#setTintList(ColorStateList)
      */
-    public void setIndeterminateTint(@Nullable ColorStateList tint) {
-        mIndeterminateTint = tint;
+    public void setIndeterminateTintList(@Nullable ColorStateList tint) {
+        mIndeterminateTintList = tint;
         mHasIndeterminateTint = true;
 
         applyIndeterminateTint();
@@ -600,23 +601,23 @@
     /**
      * @return the tint applied to the indeterminate drawable
      * @attr ref android.R.styleable#ProgressBar_indeterminateTint
-     * @see #setIndeterminateTint(ColorStateList)
+     * @see #setIndeterminateTintList(ColorStateList)
      */
     @Nullable
-    public ColorStateList getIndeterminateTint() {
-        return mIndeterminateTint;
+    public ColorStateList getIndeterminateTintList() {
+        return mIndeterminateTintList;
     }
 
     /**
      * Specifies the blending mode used to apply the tint specified by
-     * {@link #setIndeterminateTint(ColorStateList)} to the indeterminate
+     * {@link #setIndeterminateTintList(ColorStateList)} to the indeterminate
      * drawable. The default mode is {@link PorterDuff.Mode#SRC_ATOP}.
      *
      * @param tintMode the blending mode used to apply the tint, may be
      *                 {@code null} to clear tint
      * @attr ref android.R.styleable#ProgressBar_indeterminateTintMode
-     * @see #setIndeterminateTint(ColorStateList)
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see #setIndeterminateTintList(ColorStateList)
+     * @see Drawable#setTintMode(PorterDuff.Mode)
      */
     public void setIndeterminateTintMode(@Nullable PorterDuff.Mode tintMode) {
         mIndeterminateTintMode = tintMode;
@@ -637,7 +638,8 @@
     private void applyIndeterminateTint() {
         if (mIndeterminateDrawable != null && mHasIndeterminateTint) {
             mIndeterminateDrawable = mIndeterminateDrawable.mutate();
-            mIndeterminateDrawable.setTint(mIndeterminateTint, mIndeterminateTintMode);
+            mIndeterminateDrawable.setTintList(mIndeterminateTintList);
+            mIndeterminateDrawable.setTintMode(mIndeterminateTintMode);
         }
     }
 
@@ -704,16 +706,17 @@
                 }
 
                 if (mHasProgressTint) {
-                    applyProgressLayerTint(R.id.progress, mProgressTint, mProgressTintMode, true);
+                    applyProgressLayerTint(R.id.progress, mProgressTintList,
+                            mProgressTintMode, true);
                 }
 
                 if (mHasProgressBackgroundTint) {
-                    applyProgressLayerTint(R.id.background, mProgressBackgroundTint,
+                    applyProgressLayerTint(R.id.background, mProgressBackgroundTintList,
                             mProgressBackgroundTintMode, false);
                 }
 
                 if (mHasSecondaryProgressTint) {
-                    applyProgressLayerTint(R.id.secondaryProgress, mSecondaryProgressTint,
+                    applyProgressLayerTint(R.id.secondaryProgress, mSecondaryProgressTintList,
                             mSecondaryProgressTintMode, false);
                 }
             }
@@ -743,16 +746,16 @@
      * Subsequent calls to {@link #setProgressDrawable(Drawable)} will
      * automatically mutate the drawable and apply the specified tint and
      * tint mode using
-     * {@link Drawable#setTint(ColorStateList, android.graphics.PorterDuff.Mode)}.
+     * {@link Drawable#setTintList(ColorStateList)}.
      *
      * @param tint the tint to apply, may be {@code null} to clear tint
      *
      * @attr ref android.R.styleable#ProgressBar_progressTint
-     * @see #getProgressTint()
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see #getProgressTintList()
+     * @see Drawable#setTintList(ColorStateList)
      */
-    public void setProgressTint(@Nullable ColorStateList tint) {
-        mProgressTint = tint;
+    public void setProgressTintList(@Nullable ColorStateList tint) {
+        mProgressTintList = tint;
         mHasProgressTint = true;
 
         applyProgressLayerTint(R.id.progress, tint, mProgressTintMode, true);
@@ -761,28 +764,28 @@
     /**
      * @return the tint applied to the progress drawable
      * @attr ref android.R.styleable#ProgressBar_progressTint
-     * @see #setProgressTint(ColorStateList)
+     * @see #setProgressTintList(ColorStateList)
      */
     @Nullable
-    public ColorStateList getProgressTint() {
-        return mProgressTint;
+    public ColorStateList getProgressTintList() {
+        return mProgressTintList;
     }
 
     /**
      * Specifies the blending mode used to apply the tint specified by
-     * {@link #setProgressTint(ColorStateList)}} to the progress
+     * {@link #setProgressTintList(ColorStateList)}} to the progress
      * indicator. The default mode is {@link PorterDuff.Mode#SRC_ATOP}.
      *
      * @param tintMode the blending mode used to apply the tint, may be
      *                 {@code null} to clear tint
      * @attr ref android.R.styleable#ProgressBar_progressTintMode
      * @see #getProgressTintMode()
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see Drawable#setTintMode(PorterDuff.Mode)
      */
     public void setProgressTintMode(@Nullable PorterDuff.Mode tintMode) {
         mProgressTintMode = tintMode;
 
-        applyProgressLayerTint(R.id.progress, mProgressTint, tintMode, true);
+        applyProgressLayerTint(R.id.progress, mProgressTintList, tintMode, true);
     }
 
     /**
@@ -807,16 +810,16 @@
      * Subsequent calls to {@link #setProgressDrawable(Drawable)} where the
      * drawable contains a progress background will automatically mutate the
      * drawable and apply the specified tint and tint mode using
-     * {@link Drawable#setTint(ColorStateList, android.graphics.PorterDuff.Mode)}.
+     * {@link Drawable#setTintList(ColorStateList)}.
      *
      * @param tint the tint to apply, may be {@code null} to clear tint
      *
      * @attr ref android.R.styleable#ProgressBar_progressBackgroundTint
-     * @see #getProgressBackgroundTint()
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see #getProgressBackgroundTintList()
+     * @see Drawable#setTintList(ColorStateList)
      */
-    public void setProgressBackgroundTint(@Nullable ColorStateList tint) {
-        mProgressBackgroundTint = tint;
+    public void setProgressBackgroundTintList(@Nullable ColorStateList tint) {
+        mProgressBackgroundTintList = tint;
         mHasProgressBackgroundTint = true;
 
         applyProgressLayerTint(R.id.background, tint, mProgressBackgroundTintMode, false);
@@ -825,28 +828,28 @@
     /**
      * @return the tint applied to the progress background
      * @attr ref android.R.styleable#ProgressBar_progressBackgroundTint
-     * @see #setProgressBackgroundTint(ColorStateList)
+     * @see #setProgressBackgroundTintList(ColorStateList)
      */
     @Nullable
-    public ColorStateList getProgressBackgroundTint() {
-        return mProgressBackgroundTint;
+    public ColorStateList getProgressBackgroundTintList() {
+        return mProgressBackgroundTintList;
     }
 
     /**
      * Specifies the blending mode used to apply the tint specified by
-     * {@link #setProgressBackgroundTint(ColorStateList)}} to the progress
+     * {@link #setProgressBackgroundTintList(ColorStateList)}} to the progress
      * background. The default mode is {@link PorterDuff.Mode#SRC_ATOP}.
      *
      * @param tintMode the blending mode used to apply the tint, may be
      *                 {@code null} to clear tint
      * @attr ref android.R.styleable#ProgressBar_progressBackgroundTintMode
-     * @see #setProgressBackgroundTint(ColorStateList)
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see #setProgressBackgroundTintList(ColorStateList)
+     * @see Drawable#setTintMode(PorterDuff.Mode)
      */
     public void setProgressBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
         mProgressBackgroundTintMode = tintMode;
 
-        applyProgressLayerTint(R.id.background, mProgressBackgroundTint, tintMode, false);
+        applyProgressLayerTint(R.id.background, mProgressBackgroundTintList, tintMode, false);
     }
 
     /**
@@ -872,16 +875,16 @@
      * Subsequent calls to {@link #setProgressDrawable(Drawable)} where the
      * drawable contains a secondary progress indicator will automatically
      * mutate the drawable and apply the specified tint and tint mode using
-     * {@link Drawable#setTint(ColorStateList, android.graphics.PorterDuff.Mode)}.
+     * {@link Drawable#setTintList(ColorStateList)}.
      *
      * @param tint the tint to apply, may be {@code null} to clear tint
      *
      * @attr ref android.R.styleable#ProgressBar_secondaryProgressTint
-     * @see #getSecondaryProgressTint()
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see #getSecondaryProgressTintList()
+     * @see Drawable#setTintList(ColorStateList)
      */
-    public void setSecondaryProgressTint(@Nullable ColorStateList tint) {
-        mSecondaryProgressTint = tint;
+    public void setSecondaryProgressTintList(@Nullable ColorStateList tint) {
+        mSecondaryProgressTintList = tint;
         mHasSecondaryProgressTint = true;
 
         applyProgressLayerTint(R.id.secondaryProgress, tint, mSecondaryProgressTintMode, false);
@@ -890,29 +893,29 @@
     /**
      * @return the tint applied to the secondary progress drawable
      * @attr ref android.R.styleable#ProgressBar_secondaryProgressTint
-     * @see #setSecondaryProgressTint(ColorStateList)
+     * @see #setSecondaryProgressTintList(ColorStateList)
      */
     @Nullable
-    public ColorStateList getSecondaryProgressTint() {
-        return mSecondaryProgressTint;
+    public ColorStateList getSecondaryProgressTintList() {
+        return mSecondaryProgressTintList;
     }
 
     /**
      * Specifies the blending mode used to apply the tint specified by
-     * {@link #setSecondaryProgressTint(ColorStateList)}} to the secondary
+     * {@link #setSecondaryProgressTintList(ColorStateList)}} to the secondary
      * progress indicator. The default mode is
      * {@link PorterDuff.Mode#SRC_ATOP}.
      *
      * @param tintMode the blending mode used to apply the tint, may be
      *                 {@code null} to clear tint
      * @attr ref android.R.styleable#ProgressBar_secondaryProgressTintMode
-     * @see #setSecondaryProgressTint(ColorStateList)
-     * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+     * @see #setSecondaryProgressTintList(ColorStateList)
+     * @see Drawable#setTintMode(PorterDuff.Mode)
      */
     public void setSecondaryProgressTintMode(@Nullable PorterDuff.Mode tintMode) {
         mSecondaryProgressTintMode = tintMode;
 
-        applyProgressLayerTint(R.id.secondaryProgress, mSecondaryProgressTint, tintMode, false);
+        applyProgressLayerTint(R.id.secondaryProgress, mSecondaryProgressTintList, tintMode, false);
     }
 
     /**
@@ -942,7 +945,8 @@
             }
 
             if (layer != null) {
-                layer.setTint(tint, tintMode);
+                layer.setTintList(tint);
+                layer.setTintMode(tintMode);
             }
         }
     }
@@ -1066,7 +1070,9 @@
             layer = d;
         }
 
-        layer.mutate().setTint(tint, tintMode);
+        layer.mutate();
+        layer.setTintList(tint);
+        layer.setTintMode(tintMode);
     }
 
     private float getScale(float progress) {
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 5c7a43b..8aef304 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -17,6 +17,8 @@
 package android.widget;
 
 import android.app.ActivityOptions;
+import android.app.ActivityThread;
+import android.app.Application;
 import android.app.PendingIntent;
 import android.appwidget.AppWidgetHostView;
 import android.content.Context;
@@ -73,17 +75,11 @@
     static final String EXTRA_REMOTEADAPTER_APPWIDGET_ID = "remoteAdapterAppWidgetId";
 
     /**
-     * User that these views should be applied as. Requires
-     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} when
-     * crossing user boundaries.
+     * Application that hosts the remote views.
+     *
+     * @hide
      */
-    private UserHandle mUser = android.os.Process.myUserHandle();
-
-    /**
-     * The package name of the package containing the layout
-     * resource. (Added to the parcel)
-     */
-    private final String mPackage;
+    private ApplicationInfo mApplication;
 
     /**
      * The resource ID of the layout file. (Added to the parcel)
@@ -275,9 +271,9 @@
     /**
      * Merges the passed RemoteViews actions with this RemoteViews actions according to
      * action-specific merge rules.
-     * 
+     *
      * @param newRv
-     * 
+     *
      * @hide
      */
     public void mergeRemoteViews(RemoteViews newRv) {
@@ -1608,16 +1604,16 @@
             int bpp = 4;
             if (c != null) {
                 switch (c) {
-                case ALPHA_8:
-                    bpp = 1;
-                    break;
-                case RGB_565:
-                case ARGB_4444:
-                    bpp = 2;
-                    break;
-                case ARGB_8888:
-                    bpp = 4;
-                    break;
+                    case ALPHA_8:
+                        bpp = 1;
+                        break;
+                    case RGB_565:
+                    case ARGB_4444:
+                        bpp = 2;
+                        break;
+                    case ARGB_8888:
+                        bpp = 4;
+                        break;
                 }
             }
             increment(b.getWidth() * b.getHeight() * bpp);
@@ -1634,20 +1630,39 @@
      * @param layoutId The id of the layout resource
      */
     public RemoteViews(String packageName, int layoutId) {
-        mPackage = packageName;
+        this(getApplicationInfo(packageName, UserHandle.myUserId()), layoutId);
+    }
+
+    /**
+     * Create a new RemoteViews object that will display the views contained
+     * in the specified layout file.
+     *
+     * @param packageName Name of the package that contains the layout resource.
+     * @param userId The user under which the package is running.
+     * @param layoutId The id of the layout resource.
+     *
+     * @hide
+     */
+    public RemoteViews(String packageName, int userId, int layoutId) {
+        this(getApplicationInfo(packageName, userId), layoutId);
+    }
+
+    /**
+     * Create a new RemoteViews object that will display the views contained
+     * in the specified layout file.
+     *
+     * @param application The application whose content is shown by the views.
+     * @param layoutId The id of the layout resource.
+     */
+    private RemoteViews(ApplicationInfo application, int layoutId) {
+        mApplication = application;
         mLayoutId = layoutId;
         mBitmapCache = new BitmapCache();
-
         // setup the memory usage statistics
         mMemoryUsageCounter = new MemoryUsageCounter();
         recalculateMemoryUsage();
     }
 
-    /** {@hide} */
-    public void setUser(UserHandle user) {
-        mUser = user;
-    }
-
     private boolean hasLandscapeAndPortraitLayouts() {
         return (mLandscape != null) && (mPortrait != null);
     }
@@ -1663,10 +1678,11 @@
         if (landscape == null || portrait == null) {
             throw new RuntimeException("Both RemoteViews must be non-null");
         }
-        if (landscape.getPackage().compareTo(portrait.getPackage()) != 0) {
-            throw new RuntimeException("Both RemoteViews must share the same package");
+        if (landscape.mApplication.uid != portrait.mApplication.uid
+                || !landscape.mApplication.packageName.equals(portrait.mApplication.packageName)) {
+            throw new RuntimeException("Both RemoteViews must share the same package and user");
         }
-        mPackage = portrait.getPackage();
+        mApplication = portrait.mApplication;
         mLayoutId = portrait.getLayoutId();
 
         mLandscape = landscape;
@@ -1703,7 +1719,7 @@
         }
 
         if (mode == MODE_NORMAL) {
-            mPackage = parcel.readString();
+            mApplication = parcel.readParcelable(null);
             mLayoutId = parcel.readInt();
             mIsWidgetCollectionChild = parcel.readInt() == 1;
 
@@ -1713,53 +1729,53 @@
                 for (int i=0; i<count; i++) {
                     int tag = parcel.readInt();
                     switch (tag) {
-                    case SetOnClickPendingIntent.TAG:
-                        mActions.add(new SetOnClickPendingIntent(parcel));
-                        break;
-                    case SetDrawableParameters.TAG:
-                        mActions.add(new SetDrawableParameters(parcel));
-                        break;
-                    case ReflectionAction.TAG:
-                        mActions.add(new ReflectionAction(parcel));
-                        break;
-                    case ViewGroupAction.TAG:
-                        mActions.add(new ViewGroupAction(parcel, mBitmapCache));
-                        break;
-                    case ReflectionActionWithoutParams.TAG:
-                        mActions.add(new ReflectionActionWithoutParams(parcel));
-                        break;
-                    case SetEmptyView.TAG:
-                        mActions.add(new SetEmptyView(parcel));
-                        break;
-                    case SetPendingIntentTemplate.TAG:
-                        mActions.add(new SetPendingIntentTemplate(parcel));
-                        break;
-                    case SetOnClickFillInIntent.TAG:
-                        mActions.add(new SetOnClickFillInIntent(parcel));
-                        break;
-                    case SetRemoteViewsAdapterIntent.TAG:
-                        mActions.add(new SetRemoteViewsAdapterIntent(parcel));
-                        break;
-                    case TextViewDrawableAction.TAG:
-                        mActions.add(new TextViewDrawableAction(parcel));
-                        break;
-                    case TextViewSizeAction.TAG:
-                        mActions.add(new TextViewSizeAction(parcel));
-                        break;
-                    case ViewPaddingAction.TAG:
-                        mActions.add(new ViewPaddingAction(parcel));
-                        break;
-                    case BitmapReflectionAction.TAG:
-                        mActions.add(new BitmapReflectionAction(parcel));
-                        break;
-                    case SetRemoteViewsAdapterList.TAG:
-                        mActions.add(new SetRemoteViewsAdapterList(parcel));
-                        break;
-                    case TextViewDrawableColorFilterAction.TAG:
-                        mActions.add(new TextViewDrawableColorFilterAction(parcel));
-                        break;
-                    default:
-                        throw new ActionException("Tag " + tag + " not found");
+                        case SetOnClickPendingIntent.TAG:
+                            mActions.add(new SetOnClickPendingIntent(parcel));
+                            break;
+                        case SetDrawableParameters.TAG:
+                            mActions.add(new SetDrawableParameters(parcel));
+                            break;
+                        case ReflectionAction.TAG:
+                            mActions.add(new ReflectionAction(parcel));
+                            break;
+                        case ViewGroupAction.TAG:
+                            mActions.add(new ViewGroupAction(parcel, mBitmapCache));
+                            break;
+                        case ReflectionActionWithoutParams.TAG:
+                            mActions.add(new ReflectionActionWithoutParams(parcel));
+                            break;
+                        case SetEmptyView.TAG:
+                            mActions.add(new SetEmptyView(parcel));
+                            break;
+                        case SetPendingIntentTemplate.TAG:
+                            mActions.add(new SetPendingIntentTemplate(parcel));
+                            break;
+                        case SetOnClickFillInIntent.TAG:
+                            mActions.add(new SetOnClickFillInIntent(parcel));
+                            break;
+                        case SetRemoteViewsAdapterIntent.TAG:
+                            mActions.add(new SetRemoteViewsAdapterIntent(parcel));
+                            break;
+                        case TextViewDrawableAction.TAG:
+                            mActions.add(new TextViewDrawableAction(parcel));
+                            break;
+                        case TextViewSizeAction.TAG:
+                            mActions.add(new TextViewSizeAction(parcel));
+                            break;
+                        case ViewPaddingAction.TAG:
+                            mActions.add(new ViewPaddingAction(parcel));
+                            break;
+                        case BitmapReflectionAction.TAG:
+                            mActions.add(new BitmapReflectionAction(parcel));
+                            break;
+                        case SetRemoteViewsAdapterList.TAG:
+                            mActions.add(new SetRemoteViewsAdapterList(parcel));
+                            break;
+                        case TextViewDrawableColorFilterAction.TAG:
+                            mActions.add(new TextViewDrawableColorFilterAction(parcel));
+                            break;
+                        default:
+                            throw new ActionException("Tag " + tag + " not found");
                     }
                 }
             }
@@ -1767,7 +1783,7 @@
             // MODE_HAS_LANDSCAPE_AND_PORTRAIT
             mLandscape = new RemoteViews(parcel, mBitmapCache);
             mPortrait = new RemoteViews(parcel, mBitmapCache);
-            mPackage = mPortrait.getPackage();
+            mApplication = mPortrait.mApplication;
             mLayoutId = mPortrait.getLayoutId();
         }
 
@@ -1787,7 +1803,7 @@
     }
 
     public String getPackage() {
-        return mPackage;
+        return mApplication.packageName;
     }
 
     /**
@@ -2557,22 +2573,20 @@
     }
 
     private Context prepareContext(Context context) {
-        Context c;
-        String packageName = mPackage;
-
-        if (packageName != null) {
-            try {
-                c = context.createPackageContextAsUser(
-                        packageName, Context.CONTEXT_RESTRICTED, mUser);
-            } catch (NameNotFoundException e) {
-                Log.e(LOG_TAG, "Package name " + packageName + " not found");
-                c = context;
+        if (mApplication != null) {
+            if (context.getUserId() == UserHandle.getUserId(mApplication.uid)
+                    && context.getPackageName().equals(mApplication.packageName)) {
+                return context;
             }
-        } else {
-            c = context;
+            try {
+                return context.createApplicationContext(mApplication,
+                        Context.CONTEXT_RESTRICTED);
+            } catch (NameNotFoundException e) {
+                Log.e(LOG_TAG, "Package name " + mApplication.packageName + " not found");
+            }
         }
 
-        return c;
+        return context;
     }
 
     /**
@@ -2605,7 +2619,7 @@
             if (mIsRoot) {
                 mBitmapCache.writeBitmapsToParcel(dest, flags);
             }
-            dest.writeString(mPackage);
+            dest.writeParcelable(mApplication, flags);
             dest.writeInt(mLayoutId);
             dest.writeInt(mIsWidgetCollectionChild ? 1 : 0);
             int count;
@@ -2631,6 +2645,28 @@
         }
     }
 
+    private static ApplicationInfo getApplicationInfo(String packageName, int userId) {
+        // Get the application for the passed in package and user.
+        Application application = ActivityThread.currentApplication();
+        if (application == null) {
+            throw new IllegalStateException("Cannot create remote views out of an aplication.");
+        }
+
+        ApplicationInfo applicationInfo = application.getApplicationInfo();
+        if (UserHandle.getUserId(applicationInfo.uid) != userId
+                || !applicationInfo.packageName.equals(packageName)) {
+            try {
+                Context context = application.getApplicationContext().createPackageContextAsUser(
+                        packageName, 0, new UserHandle(userId));
+                applicationInfo = context.getApplicationInfo();
+            } catch (NameNotFoundException nnfe) {
+                throw new IllegalArgumentException("No such package " + packageName);
+            }
+        }
+
+        return applicationInfo;
+    }
+
     /**
      * Parcelable.Creator that instantiates RemoteViews objects
      */
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index bbe6f9e..5d21e0b 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -114,8 +114,6 @@
     // construction (happens when we have a cached FixedSizeRemoteViewsCache).
     private boolean mDataReady = false;
 
-    int mUserId;
-
     /**
      * An interface for the RemoteAdapter to notify other classes when adapters
      * are actually connected to/disconnected from their actual services.
@@ -159,9 +157,8 @@
                     RemoteViewsAdapter adapter;
                     final AppWidgetManager mgr = AppWidgetManager.getInstance(context);
                     if ((adapter = mAdapter.get()) != null) {
-                        checkInteractAcrossUsersPermission(context, adapter.mUserId);
-                        mgr.bindRemoteViewsService(appWidgetId, intent, asBinder(),
-                                new UserHandle(adapter.mUserId));
+                        mgr.bindRemoteViewsService(context.getPackageName(), appWidgetId,
+                                intent, asBinder());
                     } else {
                         Slog.w(TAG, "bind: adapter was null");
                     }
@@ -179,9 +176,7 @@
                 RemoteViewsAdapter adapter;
                 final AppWidgetManager mgr = AppWidgetManager.getInstance(context);
                 if ((adapter = mAdapter.get()) != null) {
-                    checkInteractAcrossUsersPermission(context, adapter.mUserId);
-                    mgr.unbindRemoteViewsService(appWidgetId, intent,
-                            new UserHandle(adapter.mUserId));
+                    mgr.unbindRemoteViewsService(context.getPackageName(), appWidgetId, intent);
                 } else {
                     Slog.w(TAG, "unbind: adapter was null");
                 }
@@ -796,12 +791,10 @@
     static class RemoteViewsCacheKey {
         final Intent.FilterComparison filter;
         final int widgetId;
-        final int userId;
 
-        RemoteViewsCacheKey(Intent.FilterComparison filter, int widgetId, int userId) {
+        RemoteViewsCacheKey(Intent.FilterComparison filter, int widgetId) {
             this.filter = filter;
             this.widgetId = widgetId;
-            this.userId = userId;
         }
 
         @Override
@@ -810,29 +803,28 @@
                 return false;
             }
             RemoteViewsCacheKey other = (RemoteViewsCacheKey) o;
-            return other.filter.equals(filter) && other.widgetId == widgetId
-                    && other.userId == userId;
+            return other.filter.equals(filter) && other.widgetId == widgetId;
         }
 
         @Override
         public int hashCode() {
-            return (filter == null ? 0 : filter.hashCode()) ^ (widgetId << 2) ^ (userId << 10);
+            return (filter == null ? 0 : filter.hashCode()) ^ (widgetId << 2);
         }
     }
 
-    public RemoteViewsAdapter(Context context, Intent intent, RemoteAdapterConnectionCallback callback) {
+    public RemoteViewsAdapter(Context context, Intent intent,
+            RemoteAdapterConnectionCallback callback) {
         mContext = context;
         mIntent = intent;
+
         mAppWidgetId = intent.getIntExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID, -1);
+
         mLayoutInflater = LayoutInflater.from(context);
         if (mIntent == null) {
             throw new IllegalArgumentException("Non-null Intent must be specified.");
         }
         mRequestedViews = new RemoteViewsFrameLayoutRefSet();
 
-        checkInteractAcrossUsersPermission(context, UserHandle.myUserId());
-        mUserId = context.getUserId();
-
         // Strip the previously injected app widget id from service intent
         if (intent.hasExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID)) {
             intent.removeExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID);
@@ -855,7 +847,7 @@
         mServiceConnection = new RemoteViewsAdapterServiceConnection(this);
 
         RemoteViewsCacheKey key = new RemoteViewsCacheKey(new Intent.FilterComparison(mIntent),
-                mAppWidgetId, mUserId);
+                mAppWidgetId);
 
         synchronized(sCachedRemoteViewsCaches) {
             if (sCachedRemoteViewsCaches.containsKey(key)) {
@@ -876,15 +868,6 @@
         }
     }
 
-    private static void checkInteractAcrossUsersPermission(Context context, int userId) {
-        if (context.getUserId() != userId
-                && context.checkCallingOrSelfPermission(MULTI_USER_PERM)
-                != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException("Must have permission " + MULTI_USER_PERM
-                    + " to inflate another user's widget");
-        }
-    }
-
     @Override
     protected void finalize() throws Throwable {
         try {
@@ -906,7 +889,7 @@
 
     public void saveRemoteViewsCache() {
         final RemoteViewsCacheKey key = new RemoteViewsCacheKey(
-                new Intent.FilterComparison(mIntent), mAppWidgetId, mUserId);
+                new Intent.FilterComparison(mIntent), mAppWidgetId);
 
         synchronized(sCachedRemoteViewsCaches) {
             // If we already have a remove runnable posted for this key, remove it.
@@ -1028,7 +1011,6 @@
         long itemId = 0;
         try {
             remoteViews = factory.getViewAt(position);
-            remoteViews.setUser(new UserHandle(mUserId));
             itemId = factory.getItemId(position);
         } catch (RemoteException e) {
             Log.e(TAG, "Error in updateRemoteViews(" + position + "): " + e.getMessage());
diff --git a/core/java/android/widget/Scroller.java b/core/java/android/widget/Scroller.java
index 1a0ce9c..5e88a96 100644
--- a/core/java/android/widget/Scroller.java
+++ b/core/java/android/widget/Scroller.java
@@ -589,10 +589,10 @@
         @Override
         public float getInterpolation(float input) {
             final float interpolated = VISCOUS_FLUID_NORMALIZE * viscousFluid(input);
-            if (input > 0) {
-                return input + VISCOUS_FLUID_OFFSET;
+            if (interpolated > 0) {
+                return interpolated + VISCOUS_FLUID_OFFSET;
             }
-            return input;
+            return interpolated;
         }
     }
 }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 52618cc..a0f7baf 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -658,6 +658,7 @@
         float dx = 0, dy = 0, r = 0;
         boolean elegant = false;
         float letterSpacing = 0;
+        String fontFeatureSettings = null;
 
         final Resources.Theme theme = context.getTheme();
 
@@ -742,6 +743,10 @@
                 case com.android.internal.R.styleable.TextAppearance_letterSpacing:
                     letterSpacing = appearance.getFloat(attr, 0);
                     break;
+
+                case com.android.internal.R.styleable.TextAppearance_fontFeatureSettings:
+                    fontFeatureSettings = appearance.getString(attr);
+                    break;
                 }
             }
 
@@ -1087,6 +1092,10 @@
             case com.android.internal.R.styleable.TextView_letterSpacing:
                 letterSpacing = a.getFloat(attr, 0);
                 break;
+
+            case com.android.internal.R.styleable.TextView_fontFeatureSettings:
+                fontFeatureSettings = a.getString(attr);
+                break;
             }
         }
         a.recycle();
@@ -1269,6 +1278,7 @@
         setRawTextSize(textSize);
         setElegantTextHeight(elegant);
         setLetterSpacing(letterSpacing);
+        setFontFeatureSettings(fontFeatureSettings);
 
         if (allCaps) {
             setTransformationMethod(new AllCapsTransformationMethod(getContext()));
@@ -2502,6 +2512,11 @@
                 com.android.internal.R.styleable.TextAppearance_letterSpacing, 0));
         }
 
+        if (appearance.hasValue(com.android.internal.R.styleable.TextAppearance_fontFeatureSettings)) {
+            setFontFeatureSettings(appearance.getString(
+                com.android.internal.R.styleable.TextAppearance_fontFeatureSettings));
+        }
+
         appearance.recycle();
     }
 
@@ -2686,6 +2701,7 @@
      * This will normally be 0.
      *
      * @see #setLetterSpacing(float)
+     * @see Paint#setLetterSpacing
      * @hide
      */
     public float getLetterSpacing() {
@@ -2697,7 +2713,7 @@
      * for slight expansion will be around 0.05.  Negative values tighten text.
      *
      * @see #getLetterSpacing()
-     * @see Paint#setFlags
+     * @see Paint#getLetterSpacing
      *
      * @attr ref android.R.styleable#TextView_letterSpacing
      * @hide
@@ -2715,6 +2731,41 @@
         }
     }
 
+    /**
+     * @return the currently set font feature settings.  Default is null.
+     *
+     * @see #setFontFeatureSettings(String)
+     * @see Paint#setFontFeatureSettings
+     * @hide
+     */
+    public String getFontFeatureSettings() {
+        return mTextPaint.getFontFeatureSettings();
+    }
+
+    /**
+     * Sets font feature settings.  The format is the same as the CSS
+     * font-feature-settings attribute:
+     * http://dev.w3.org/csswg/css-fonts/#propdef-font-feature-settings
+     *
+     * @see #getFontFeatureSettings()
+     * @see Paint#getFontFeatureSettings
+     *
+     * @attr ref android.R.styleable#TextView_fontFeatureSettings
+     * @hide
+     */
+    @android.view.RemotableViewMethod
+    public void setFontFeatureSettings(String fontFeatureSettings) {
+        if (fontFeatureSettings != mTextPaint.getFontFeatureSettings()) {
+            mTextPaint.setFontFeatureSettings(fontFeatureSettings);
+
+            if (mLayout != null) {
+                nullLayouts();
+                requestLayout();
+                invalidate();
+            }
+        }
+    }
+
 
     /**
      * Sets the text color for all the states (normal, selected,
diff --git a/core/java/android/widget/ViewFlipper.java b/core/java/android/widget/ViewFlipper.java
index b152297..cf1f554 100644
--- a/core/java/android/widget/ViewFlipper.java
+++ b/core/java/android/widget/ViewFlipper.java
@@ -21,8 +21,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.TypedArray;
-import android.os.Handler;
-import android.os.Message;
+import android.os.*;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.accessibility.AccessibilityEvent;
@@ -90,7 +89,16 @@
         final IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_SCREEN_OFF);
         filter.addAction(Intent.ACTION_USER_PRESENT);
-        getContext().registerReceiver(mReceiver, filter, null, mHandler);
+
+        // OK, this is gross but needed. This class is supported by the
+        // remote views machanism and as a part of that the remote views
+        // can be inflated by a context for another user without the app
+        // having interact users permission - just for loading resources.
+        // For exmaple, when adding widgets from a user profile to the
+        // home screen. Therefore, we register the receiver as the current
+        // user not the one the context is for.
+        getContext().registerReceiverAsUser(mReceiver, android.os.Process.myUserHandle(),
+                filter, null, mHandler);
 
         if (mAutoStart) {
             // Automatically start when requested
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index f0e7215..59891d6 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -229,7 +229,7 @@
         }
         mAlwaysUseOption = alwaysUseOption;
 
-        int count = mAdapter.getCount();
+        int count = mAdapter.mList.size();
         if (mLaunchedFromUid < 0 || UserHandle.isIsolated(mLaunchedFromUid)) {
             // Gulp!
             finish();
diff --git a/core/java/com/android/internal/app/ToolbarActionBar.java b/core/java/com/android/internal/app/ToolbarActionBar.java
index 298dd44..96d7192 100644
--- a/core/java/com/android/internal/app/ToolbarActionBar.java
+++ b/core/java/com/android/internal/app/ToolbarActionBar.java
@@ -179,7 +179,7 @@
 
     @Override
     public ActionMode startActionMode(ActionMode.Callback callback) {
-        return mToolbar.startActionMode(callback);
+        return null;
     }
 
     @Override
diff --git a/core/java/com/android/internal/appwidget/IAppWidgetHost.aidl b/core/java/com/android/internal/appwidget/IAppWidgetHost.aidl
index 6d51d38..a7f7fe1 100644
--- a/core/java/com/android/internal/appwidget/IAppWidgetHost.aidl
+++ b/core/java/com/android/internal/appwidget/IAppWidgetHost.aidl
@@ -16,15 +16,16 @@
 
 package com.android.internal.appwidget;
 
+import android.content.pm.ApplicationInfo;
 import android.content.ComponentName;
 import android.appwidget.AppWidgetProviderInfo;
 import android.widget.RemoteViews;
 
 /** {@hide} */
 oneway interface IAppWidgetHost {
-    void updateAppWidget(int appWidgetId, in RemoteViews views, int userId);
-    void providerChanged(int appWidgetId, in AppWidgetProviderInfo info, int userId);
-    void providersChanged(int userId);
-    void viewDataChanged(int appWidgetId, int viewId, int userId);
+    void updateAppWidget(int appWidgetId, in RemoteViews views);
+    void providerChanged(int appWidgetId, in AppWidgetProviderInfo info);
+    void providersChanged();
+    void viewDataChanged(int appWidgetId, int viewId);
 }
 
diff --git a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
index 5214dd9..9da1c9d 100644
--- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
+++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
@@ -18,6 +18,8 @@
 
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.ApplicationInfo;
 import android.appwidget.AppWidgetProviderInfo;
 import com.android.internal.appwidget.IAppWidgetHost;
 import android.os.Bundle;
@@ -30,34 +32,37 @@
     //
     // for AppWidgetHost
     //
-    int[] startListening(IAppWidgetHost host, String packageName, int hostId,
-            out List<RemoteViews> updatedViews, int userId);
-    void stopListening(int hostId, int userId);
-    int allocateAppWidgetId(String packageName, int hostId, int userId);
-    void deleteAppWidgetId(int appWidgetId, int userId);
-    void deleteHost(int hostId, int userId);
-    void deleteAllHosts(int userId);
-    RemoteViews getAppWidgetViews(int appWidgetId, int userId);
-    int[] getAppWidgetIdsForHost(int hostId, int userId);
+    int[] startListening(IAppWidgetHost host, String callingPackage, int hostId,
+            out List<RemoteViews> updatedViews);
+    void stopListening(String callingPackage, int hostId);
+    int allocateAppWidgetId(String callingPackage, int hostId);
+    void deleteAppWidgetId(String callingPackage, int appWidgetId);
+    void deleteHost(String packageName, int hostId);
+    void deleteAllHosts();
+    RemoteViews getAppWidgetViews(String callingPackage, int appWidgetId);
+    int[] getAppWidgetIdsForHost(String callingPackage, int hostId);
+    IntentSender createAppWidgetConfigIntentSender(String callingPackage, in Intent intent);
 
     //
     // for AppWidgetManager
     //
-    void updateAppWidgetIds(in int[] appWidgetIds, in RemoteViews views, int userId);
-    void updateAppWidgetOptions(int appWidgetId, in Bundle extras, int userId);
-    Bundle getAppWidgetOptions(int appWidgetId, int userId);
-    void partiallyUpdateAppWidgetIds(in int[] appWidgetIds, in RemoteViews views, int userId);
-    void updateAppWidgetProvider(in ComponentName provider, in RemoteViews views, int userId);
-    void notifyAppWidgetViewDataChanged(in int[] appWidgetIds, int viewId, int userId);
-    List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter, int userId);
-    AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId, int userId);
+    void updateAppWidgetIds(String callingPackage, in int[] appWidgetIds, in RemoteViews views);
+    void updateAppWidgetOptions(String callingPackage, int appWidgetId, in Bundle extras);
+    Bundle getAppWidgetOptions(String callingPackage, int appWidgetId);
+    void partiallyUpdateAppWidgetIds(String callingPackage, in int[] appWidgetIds,
+            in RemoteViews views);
+    void updateAppWidgetProvider(in ComponentName provider, in RemoteViews views);
+    void notifyAppWidgetViewDataChanged(String packageName, in int[] appWidgetIds, int viewId);
+    List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter,
+            in int[] profileIds);
+    AppWidgetProviderInfo getAppWidgetInfo(String callingPackage, int appWidgetId);
     boolean hasBindAppWidgetPermission(in String packageName, int userId);
-    void setBindAppWidgetPermission(in String packageName, in boolean permission, int userId);
-    void bindAppWidgetId(int appWidgetId, in ComponentName provider, in Bundle options, int userId);
-    boolean bindAppWidgetIdIfAllowed(in String packageName, int appWidgetId,
-            in ComponentName provider, in Bundle options, int userId);
-    void bindRemoteViewsService(int appWidgetId, in Intent intent, in IBinder connection, int userId);
-    void unbindRemoteViewsService(int appWidgetId, in Intent intent, int userId);
-    int[] getAppWidgetIds(in ComponentName provider, int userId);
+    void setBindAppWidgetPermission(in String packageName, int userId, in boolean permission);
+    boolean bindAppWidgetId(in String callingPackage, int appWidgetId,
+            int providerProfileId, in ComponentName providerComponent, in Bundle options);
+    void bindRemoteViewsService(String callingPackage, int appWidgetId, in Intent intent,
+            in IBinder connection);
+    void unbindRemoteViewsService(String callingPackage, int appWidgetId, in Intent intent);
+    int[] getAppWidgetIds(in ComponentName providerComponent);
 }
 
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 969c0db..69ffbfe 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -35,9 +35,11 @@
     void setHardKeyboardStatus(boolean available, boolean enabled);
     void setWindowState(int window, int state);
     void buzzBeepBlinked();
+    void notificationLightOff();
+    void notificationLightPulse(int argb, int millisOn, int millisOff);
 
     void showRecentApps(boolean triggeredFromAltTab);
-    void hideRecentApps(boolean triggeredFromAltTab);
+    void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
     void toggleRecentApps();
     void preloadRecentApps();
     void cancelPreloadRecentApps();
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 243ce97..50c82bb 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -55,7 +55,7 @@
     void setWindowState(int window, int state);
 
     void showRecentApps(boolean triggeredFromAltTab);
-    void hideRecentApps(boolean triggeredFromAltTab);
+    void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
     void toggleRecentApps();
     void preloadRecentApps();
     void cancelPreloadRecentApps();
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 3a02ab9..c4c4362 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -363,11 +363,7 @@
         if (argv[i][1] == '-' && argv[i][2] == 0) {
             return i+1;
         }
-
-        JavaVMOption opt;
-        memset(&opt, 0, sizeof(opt));
-        opt.optionString = (char*)argv[i];
-        mOptions.add(opt);
+        addOption(argv[i]);
     }
     return i;
 }
@@ -401,6 +397,14 @@
     //ALOGD("language=%s region=%s\n", language, region);
 }
 
+void AndroidRuntime::addOption(const char* optionString, void* extraInfo)
+{
+    JavaVMOption opt;
+    opt.optionString = optionString;
+    opt.extraInfo = extraInfo;
+    mOptions.add(opt);
+}
+
 /*
  * Parse a property containing space-separated options that should be
  * passed directly to the VM, e.g. "-Xmx32m -verbose:gc -Xregenmap".
@@ -413,8 +417,6 @@
  */
 void AndroidRuntime::parseExtraOpts(char* extraOptsBuf, const char* quotingArg)
 {
-    JavaVMOption opt;
-    memset(&opt, 0, sizeof(opt));
     char* start = extraOptsBuf;
     char* end = NULL;
     while (*start != '\0') {
@@ -429,13 +431,10 @@
         if (*end == ' ')
             *end++ = '\0';          /* mark end, advance to indicate more */
 
-        opt.optionString = start;
         if (quotingArg != NULL) {
-            JavaVMOption quotingOpt;
-            quotingOpt.optionString = quotingArg;
-            mOptions.add(quotingOpt);
+            addOption(quotingArg);
         }
-        mOptions.add(opt);
+        addOption(start);
         start = end;
     }
 }
@@ -463,13 +462,35 @@
     if (buffer[runtimeArgLen] == '\0') {
         return false;
     }
+    addOption(buffer);
+    return true;
+}
 
-    JavaVMOption opt;
-    memset(&opt, 0, sizeof(opt));
-
-    opt.optionString = buffer;
-    mOptions.add(opt);
-
+/*
+ * Reads a "property" into "buffer". If the property is non-empty, it
+ * is treated as a dex2oat compiler option that should be
+ * passed as a quoted option, e.g. "-Ximage-compiler-option --compiler-filter=verify-none".
+ *
+ * The "compilerArg" is a prefix for the option such as "--compiler-filter=".
+ *
+ * The "quotingArg" should be "-Ximage-compiler-option" or "-Xcompiler-option".
+ *
+ * If an option is found, it is added to mOptions and true is
+ * returned. Otherwise false is returned.
+ */
+bool AndroidRuntime::parseCompilerOption(const char* property,
+                                         char* buffer,
+                                         const char* compilerArg,
+                                         const char* quotingArg)
+{
+    strcpy(buffer, compilerArg);
+    size_t compilerArgLen = strlen(compilerArg);
+    property_get(property, buffer+compilerArgLen, "");
+    if (buffer[compilerArgLen] == '\0') {
+        return false;
+    }
+    addOption(quotingArg);
+    addOption(buffer);
     return true;
 }
 
@@ -497,22 +518,10 @@
     if (buffer[runtimeArgLen] == '\0') {
         return false;
     }
-
-    JavaVMOption opt;
-    memset(&opt, 0, sizeof(opt));
-
-    opt.optionString = quotingArg;
-    mOptions.add(opt);
-
-    opt.optionString = "--runtime-arg";
-    mOptions.add(opt);
-
-    opt.optionString = quotingArg;
-    mOptions.add(opt);
-
-    opt.optionString = buffer;
-    mOptions.add(opt);
-
+    addOption(quotingArg);
+    addOption("--runtime-arg");
+    addOption(quotingArg);
+    addOption(buffer);
     return true;
 }
 
@@ -536,7 +545,6 @@
 {
     int result = -1;
     JavaVMInitArgs initArgs;
-    JavaVMOption opt;
     char propBuf[PROPERTY_VALUE_MAX];
     char stackTraceFileBuf[sizeof("-Xstacktracefile:")-1 + PROPERTY_VALUE_MAX];
     char dexoptFlagsBuf[PROPERTY_VALUE_MAX];
@@ -556,9 +564,12 @@
     char dex2oatXmxImageFlagsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
     char dex2oatXmsFlagsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
     char dex2oatXmxFlagsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
+    char dex2oatCompilerFilterBuf[sizeof("--compiler-filter=")-1 + PROPERTY_VALUE_MAX];
+    char dex2oatImageCompilerFilterBuf[sizeof("--compiler-filter=")-1 + PROPERTY_VALUE_MAX];
     char dex2oatFlagsBuf[PROPERTY_VALUE_MAX];
     char dex2oatImageFlagsBuf[PROPERTY_VALUE_MAX];
     char extraOptsBuf[PROPERTY_VALUE_MAX];
+    char voldDecryptBuf[PROPERTY_VALUE_MAX];
     enum {
       kEMDefault,
       kEMIntPortable,
@@ -594,16 +605,13 @@
     ALOGD("CheckJNI is %s\n", checkJni ? "ON" : "OFF");
     if (checkJni) {
         /* extended JNI checking */
-        opt.optionString = "-Xcheck:jni";
-        mOptions.add(opt);
+        addOption("-Xcheck:jni");
 
         /* set a cap on JNI global references */
-        opt.optionString = "-Xjnigreflimit:2000";
-        mOptions.add(opt);
+        addOption("-Xjnigreflimit:2000");
 
         /* with -Xcheck:jni, this provides a JNI function call trace */
-        //opt.optionString = "-verbose:jni";
-        //mOptions.add(opt);
+        //addOption("-verbose:jni");
     }
 
     property_get("dalvik.vm.execution-mode", propBuf, "");
@@ -620,15 +628,13 @@
     property_get("dalvik.vm.check-dex-sum", propBuf, "");
     if (strcmp(propBuf, "true") == 0) {
         /* perform additional DEX checksum tests */
-        opt.optionString = "-Xcheckdexsum";
-        mOptions.add(opt);
+        addOption("-Xcheckdexsum");
     }
 
     property_get("log.redirect-stdio", propBuf, "");
     if (strcmp(propBuf, "true") == 0) {
         /* convert stdout/stderr to log messages */
-        opt.optionString = "-Xlog-stdio";
-        mOptions.add(opt);
+        addOption("-Xlog-stdio");
     }
 
     strcpy(enableAssertBuf, "-ea:");
@@ -638,8 +644,7 @@
         if (strcmp(enableAssertBuf+sizeof("-ea:")-1, "all") == 0)
             enableAssertBuf[3] = '\0'; // truncate to "-ea"
         ALOGI("Assertions enabled: '%s'\n", enableAssertBuf);
-        opt.optionString = enableAssertBuf;
-        mOptions.add(opt);
+        addOption(enableAssertBuf);
     } else {
         ALOGV("Assertions disabled\n");
     }
@@ -650,27 +655,18 @@
     }
 
     /* route exit() to our handler */
-    opt.extraInfo = (void*) runtime_exit;
-    opt.optionString = "exit";
-    mOptions.add(opt);
+    addOption("exit", (void*) runtime_exit);
 
     /* route fprintf() to our handler */
-    opt.extraInfo = (void*) runtime_vfprintf;
-    opt.optionString = "vfprintf";
-    mOptions.add(opt);
+    addOption("vfprintf", (void*) runtime_vfprintf);
 
     /* register the framework-specific "is sensitive thread" hook */
-    opt.extraInfo = (void*) runtime_isSensitiveThread;
-    opt.optionString = "sensitiveThread";
-    mOptions.add(opt);
-
-    opt.extraInfo = NULL;
+    addOption("sensitiveThread", (void*) runtime_isSensitiveThread);
 
     /* enable verbose; standard options are { jni, gc, class } */
-    //options[curOpt++].optionString = "-verbose:jni";
-    opt.optionString = "-verbose:gc";
-    mOptions.add(opt);
-    //options[curOpt++].optionString = "-verbose:class";
+    //addOption("-verbose:jni");
+    addOption("-verbose:gc");
+    //addOption("-verbose:class");
 
     /*
      * The default starting and maximum size of the heap.  Larger
@@ -680,8 +676,7 @@
     parseRuntimeOption("dalvik.vm.heapsize", heapsizeOptsBuf, "-Xmx", "16m");
 
     // Increase the main thread's interpreter stack size for bug 6315322.
-    opt.optionString = "-XX:mainThreadStackSize=24K";
-    mOptions.add(opt);
+    addOption("-XX:mainThreadStackSize=24K");
 
     // Set the max jit code cache size.  Note: size of 0 will disable the JIT.
     parseRuntimeOption("dalvik.vm.jit.codecachesize",
@@ -697,8 +692,7 @@
 
     property_get("ro.config.low_ram", propBuf, "");
     if (strcmp(propBuf, "true") == 0) {
-      opt.optionString = "-XX:LowMemoryMode";
-      mOptions.add(opt);
+      addOption("-XX:LowMemoryMode");
     }
 
     parseRuntimeOption("dalvik.vm.gctype", gctypeOptsBuf, "-Xgc:");
@@ -723,8 +717,7 @@
             }
 
             if (val != NULL) {
-                opt.optionString = val;
-                mOptions.add(opt);
+                addOption(val);
             }
         }
 
@@ -739,27 +732,22 @@
             }
 
             if (val != NULL) {
-                opt.optionString = val;
-                mOptions.add(opt);
+                addOption(val);
             }
         }
 
         opc = strstr(dexoptFlagsBuf, "m=y");    /* register map */
         if (opc != NULL) {
-            opt.optionString = "-Xgenregmap";
-            mOptions.add(opt);
+            addOption("-Xgenregmap");
 
             /* turn on precise GC while we're at it */
-            opt.optionString = "-Xgc:precise";
-            mOptions.add(opt);
+            addOption("-Xgc:precise");
         }
     }
 
     /* enable debugging; set suspend=y to pause during VM init */
     /* use android ADB transport */
-    opt.optionString =
-        "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y";
-    mOptions.add(opt);
+    addOption("-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y");
 
     parseRuntimeOption("dalvik.vm.lockprof.threshold",
                        lockProfThresholdBuf,
@@ -772,14 +760,11 @@
     parseRuntimeOption("dalvik.vm.jit.method", jitMethodBuf, "-Xjitmethod:");
 
     if (executionMode == kEMIntPortable) {
-        opt.optionString = "-Xint:portable";
-        mOptions.add(opt);
+        addOption("-Xint:portable");
     } else if (executionMode == kEMIntFast) {
-        opt.optionString = "-Xint:fast";
-        mOptions.add(opt);
+        addOption("-Xint:fast");
     } else if (executionMode == kEMJitCompiler) {
-        opt.optionString = "-Xint:jit";
-        mOptions.add(opt);
+        addOption("-Xint:jit");
     }
 
     // libart tolerates libdvm flags, but not vice versa, so only pass some options if libart.
@@ -787,11 +772,27 @@
     bool libart = (strncmp(dalvikVmLibBuf, "libart", 6) == 0);
 
     if (libart) {
+        // If we booting without the real /data, don't spend time compiling.
+        property_get("vold.decrypt", voldDecryptBuf, "");
+        bool skip_compilation = ((strcmp(voldDecryptBuf, "trigger_restart_min_framework") == 0) ||
+                                 (strcmp(voldDecryptBuf, "1") == 0));
+
         // Extra options for boot.art/boot.oat image generation.
         parseCompilerRuntimeOption("dalvik.vm.image-dex2oat-Xms", dex2oatXmsImageFlagsBuf,
                                    "-Xms", "-Ximage-compiler-option");
         parseCompilerRuntimeOption("dalvik.vm.image-dex2oat-Xmx", dex2oatXmxImageFlagsBuf,
                                    "-Xmx", "-Ximage-compiler-option");
+        if (skip_compilation) {
+            addOption("-Ximage-compiler-option");
+            addOption("--compiler-filter=verify-none");
+        } else {
+            parseCompilerOption("dalvik.vm.image-dex2oat-filter", dex2oatImageCompilerFilterBuf,
+                                "--compiler-filter=", "-Ximage-compiler-option");
+        }
+        addOption("-Ximage-compiler-option");
+        addOption("--image-classes-zip=/system/framework/framework.jar");
+        addOption("-Ximage-compiler-option");
+        addOption("--image-classes=preloaded-classes");
         property_get("dalvik.vm.image-dex2oat-flags", dex2oatImageFlagsBuf, "");
         parseExtraOpts(dex2oatImageFlagsBuf, "-Ximage-compiler-option");
 
@@ -800,8 +801,16 @@
                                    "-Xms", "-Xcompiler-option");
         parseCompilerRuntimeOption("dalvik.vm.dex2oat-Xmx", dex2oatXmxFlagsBuf,
                                    "-Xmx", "-Xcompiler-option");
+        if (skip_compilation) {
+            addOption("-Xcompiler-option");
+            addOption("--compiler-filter=interpret-only");
+        } else {
+            parseCompilerOption("dalvik.vm.dex2oat-filter", dex2oatCompilerFilterBuf,
+                                "--compiler-filter=", "-Xcompiler-option");
+        }
         property_get("dalvik.vm.dex2oat-flags", dex2oatFlagsBuf, "");
         parseExtraOpts(dex2oatFlagsBuf, "-Xcompiler-option");
+
     }
 
     /* extra options; parse this late so it overrides others */
@@ -813,11 +822,8 @@
         strcpy(langOption, "-Duser.language=");
         strcpy(regionOption, "-Duser.region=");
         readLocale(langOption, regionOption);
-        opt.extraInfo = NULL;
-        opt.optionString = langOption;
-        mOptions.add(opt);
-        opt.optionString = regionOption;
-        mOptions.add(opt);
+        addOption(langOption);
+        addOption(regionOption);
     }
 
     /*
@@ -827,16 +833,14 @@
         // Whether or not the profiler should be enabled.
         property_get("dalvik.vm.profiler", propBuf, "0");
         if (propBuf[0] == '1') {
-            opt.optionString = "-Xenable-profiler";
-            mOptions.add(opt);
+            addOption("-Xenable-profiler");
         }
 
         // Whether the profile should start upon app startup or be delayed by some random offset
         // (in seconds) that is bound between 0 and a fixed value.
         property_get("dalvik.vm.profile.start-immed", propBuf, "0");
         if (propBuf[0] == '1') {
-            opt.optionString = "-Xprofile-start-immediately";
-            mOptions.add(opt);
+            addOption("-Xprofile-start-immediately");
         }
 
         // Number of seconds during profile runs.
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 235e4f2..f6ced09 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -430,9 +430,9 @@
 
     static void setFontFeatureSettings(JNIEnv* env, jobject clazz, jlong paintHandle, jstring settings) {
         Paint* paint = reinterpret_cast<Paint*>(paintHandle);
-        if (!settings)
+        if (!settings) {
             paint->setFontFeatureSettings(std::string());
-        else {
+        } else {
             ScopedUtfChars settingsChars(env, settings);
             paint->setFontFeatureSettings(std::string(settingsChars.c_str(), settingsChars.size()));
         }
diff --git a/core/jni/android_hardware_SoundTrigger.cpp b/core/jni/android_hardware_SoundTrigger.cpp
index c9a0b1e..f0d7a35 100644
--- a/core/jni/android_hardware_SoundTrigger.cpp
+++ b/core/jni/android_hardware_SoundTrigger.cpp
@@ -29,6 +29,7 @@
 #include <utils/Vector.h>
 #include <binder/IMemory.h>
 #include <binder/MemoryDealer.h>
+#include "android_media_AudioFormat.h"
 
 using namespace android;
 
@@ -63,6 +64,7 @@
 static jclass gSoundModelClass;
 static struct {
     jfieldID    uuid;
+    jfieldID    vendorUuid;
     jfieldID    data;
 } gSoundModelFields;
 
@@ -110,6 +112,7 @@
 static struct {
     jfieldID id;
     jfieldID recognitionModes;
+    jfieldID coarseConfidenceLevel;
     jfieldID confidenceLevels;
 } gKeyphraseRecognitionExtraFields;
 
@@ -122,6 +125,16 @@
     jfieldID confidenceLevel;
 } gConfidenceLevelFields;
 
+static const char* const kAudioFormatClassPathName =
+                             "android/media/AudioFormat";
+static jclass gAudioFormatClass;
+static jmethodID gAudioFormatCstor;
+
+static const char* const kSoundModelEventClassPathName =
+                                     "android/hardware/soundtrigger/SoundTrigger$SoundModelEvent";
+static jclass gSoundModelEventClass;
+static jmethodID   gSoundModelEventCstor;
+
 static Mutex gLock;
 
 enum {
@@ -137,6 +150,8 @@
 enum  {
     SOUNDTRIGGER_EVENT_RECOGNITION = 1,
     SOUNDTRIGGER_EVENT_SERVICE_DIED = 2,
+    SOUNDTRIGGER_EVENT_SOUNDMODEL = 3,
+    SOUNDTRIGGER_EVENT_SERVICE_STATE_CHANGE = 4,
 };
 
 // ----------------------------------------------------------------------------
@@ -148,6 +163,8 @@
     ~JNISoundTriggerCallback();
 
     virtual void onRecognitionEvent(struct sound_trigger_recognition_event *event);
+    virtual void onSoundModelEvent(struct sound_trigger_model_event *event);
+    virtual void onServiceStateChange(sound_trigger_service_state_t state);
     virtual void onServiceDied();
 
 private:
@@ -183,10 +200,9 @@
 void JNISoundTriggerCallback::onRecognitionEvent(struct sound_trigger_recognition_event *event)
 {
     JNIEnv *env = AndroidRuntime::getJNIEnv();
-
-    jobject jEvent;
-
+    jobject jEvent = NULL;
     jbyteArray jData = NULL;
+
     if (event->data_size) {
         jData = env->NewByteArray(event->data_size);
         jbyte *nData = env->GetByteArrayElements(jData, NULL);
@@ -194,6 +210,15 @@
         env->ReleaseByteArrayElements(jData, nData, 0);
     }
 
+    jobject jAudioFormat = NULL;
+    if (event->trigger_in_data) {
+        jAudioFormat = env->NewObject(gAudioFormatClass,
+                                    gAudioFormatCstor,
+                                    audioFormatFromNative(event->audio_config.format),
+                                    event->audio_config.sample_rate,
+                                    inChannelMaskFromNative(event->audio_config.channel_mask));
+
+    }
     if (event->type == SOUND_MODEL_TYPE_KEYPHRASE) {
         struct sound_trigger_phrase_recognition_event *phraseEvent =
                 (struct sound_trigger_phrase_recognition_event *)event;
@@ -225,6 +250,7 @@
                                                gKeyphraseRecognitionExtraCstor,
                                                phraseEvent->phrase_extras[i].id,
                                                phraseEvent->phrase_extras[i].recognition_modes,
+                                               phraseEvent->phrase_extras[i].confidence_level,
                                                jConfidenceLevels);
 
             if (jNewExtra == NULL) {
@@ -236,19 +262,63 @@
         }
         jEvent = env->NewObject(gKeyphraseRecognitionEventClass, gKeyphraseRecognitionEventCstor,
                                 event->status, event->model, event->capture_available,
-                               event->capture_session, event->capture_delay_ms,
-                               event->capture_preamble_ms, jData,
-                               phraseEvent->key_phrase_in_capture, jExtras);
+                                event->capture_session, event->capture_delay_ms,
+                                event->capture_preamble_ms, event->trigger_in_data,
+                                jAudioFormat, jData, jExtras);
+        env->DeleteLocalRef(jAudioFormat);
+        env->DeleteLocalRef(jData);
     } else {
         jEvent = env->NewObject(gRecognitionEventClass, gRecognitionEventCstor,
                                 event->status, event->model, event->capture_available,
                                 event->capture_session, event->capture_delay_ms,
-                                event->capture_preamble_ms, jData);
+                                event->capture_preamble_ms, event->trigger_in_data,
+                                jAudioFormat, jData);
+        env->DeleteLocalRef(jAudioFormat);
+        env->DeleteLocalRef(jData);
     }
 
 
     env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
                               SOUNDTRIGGER_EVENT_RECOGNITION, 0, 0, jEvent);
+
+    env->DeleteLocalRef(jEvent);
+    if (env->ExceptionCheck()) {
+        ALOGW("An exception occurred while notifying an event.");
+        env->ExceptionClear();
+    }
+}
+
+void JNISoundTriggerCallback::onSoundModelEvent(struct sound_trigger_model_event *event)
+{
+    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    jobject jEvent = NULL;
+    jbyteArray jData = NULL;
+
+    if (event->data_size) {
+        jData = env->NewByteArray(event->data_size);
+        jbyte *nData = env->GetByteArrayElements(jData, NULL);
+        memcpy(nData, (char *)event + event->data_offset, event->data_size);
+        env->ReleaseByteArrayElements(jData, nData, 0);
+    }
+
+    jEvent = env->NewObject(gSoundModelEventClass, gSoundModelEventCstor,
+                            event->status, event->model, jData);
+
+    env->DeleteLocalRef(jData);
+    env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
+                              SOUNDTRIGGER_EVENT_SOUNDMODEL, 0, 0, jEvent);
+    env->DeleteLocalRef(jEvent);
+    if (env->ExceptionCheck()) {
+        ALOGW("An exception occurred while notifying an event.");
+        env->ExceptionClear();
+    }
+}
+
+void JNISoundTriggerCallback::onServiceStateChange(sound_trigger_service_state_t state)
+{
+    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
+                                        SOUNDTRIGGER_EVENT_SERVICE_STATE_CHANGE, state, 0, NULL);
     if (env->ExceptionCheck()) {
         ALOGW("An exception occurred while notifying an event.");
         env->ExceptionClear();
@@ -336,7 +406,7 @@
                                    SOUND_TRIGGER_MAX_STRING_LEN);
         jstring uuid = env->NewStringUTF(str);
 
-        ALOGV("listModules module %d id %d description %s maxSoundModels %d",
+        ALOGV("listModules module %zu id %d description %s maxSoundModels %d",
               i, nModules[i].handle, nModules[i].properties.description,
               nModules[i].properties.max_sound_models);
 
@@ -351,7 +421,8 @@
                                                nModules[i].properties.capture_transition,
                                                nModules[i].properties.max_buffer_ms,
                                                nModules[i].properties.concurrent_capture,
-                                               nModules[i].properties.power_consumption_mw);
+                                               nModules[i].properties.power_consumption_mw,
+                                               nModules[i].properties.trigger_in_event);
 
         env->DeleteLocalRef(implementor);
         env->DeleteLocalRef(description);
@@ -463,6 +534,18 @@
     env->ReleaseStringUTFChars(jUuidString, nUuidString);
     env->DeleteLocalRef(jUuidString);
 
+    sound_trigger_uuid_t nVendorUuid;
+    jUuid = env->GetObjectField(jSoundModel, gSoundModelFields.vendorUuid);
+    if (jUuid != NULL) {
+        jUuidString = (jstring)env->CallObjectMethod(jUuid, gUUIDMethods.toString);
+        nUuidString = env->GetStringUTFChars(jUuidString, NULL);
+        SoundTrigger::stringToGuid(nUuidString, &nVendorUuid);
+        env->ReleaseStringUTFChars(jUuidString, nUuidString);
+        env->DeleteLocalRef(jUuidString);
+    } else {
+        SoundTrigger::stringToGuid("00000000-0000-0000-0000-000000000000", &nVendorUuid);
+    }
+
     jData = (jbyteArray)env->GetObjectField(jSoundModel, gSoundModelFields.data);
     if (jData == NULL) {
         status = SOUNDTRIGGER_STATUS_BAD_VALUE;
@@ -491,6 +574,7 @@
 
     nSoundModel->type = type;
     nSoundModel->uuid = nUuid;
+    nSoundModel->vendor_uuid = nVendorUuid;
     nSoundModel->data_size = size;
     nSoundModel->data_offset = offset;
     memcpy((char *)nSoundModel + offset, nData, size);
@@ -507,7 +591,7 @@
 
         size_t numPhrases = env->GetArrayLength(jPhrases);
         phraseModel->num_phrases = numPhrases;
-        ALOGV("loadSoundModel numPhrases %d", numPhrases);
+        ALOGV("loadSoundModel numPhrases %zu", numPhrases);
         for (size_t i = 0; i < numPhrases; i++) {
             jobject jPhrase = env->GetObjectArrayElement(jPhrases, i);
             phraseModel->phrases[i].id =
@@ -539,7 +623,7 @@
             env->DeleteLocalRef(jLocale);
             env->ReleaseStringUTFChars(jText, nText);
             env->DeleteLocalRef(jText);
-            ALOGV("loadSoundModel phrases %d text %s locale %s",
+            ALOGV("loadSoundModel phrases %zu text %s locale %s",
                   i, phraseModel->phrases[i].text, phraseModel->phrases[i].locale);
             env->DeleteLocalRef(jPhrase);
         }
@@ -640,13 +724,15 @@
                                                 gKeyphraseRecognitionExtraFields.id);
         config->phrases[i].recognition_modes = env->GetIntField(jPhrase,
                                                 gKeyphraseRecognitionExtraFields.recognitionModes);
+        config->phrases[i].confidence_level = env->GetIntField(jPhrase,
+                                            gKeyphraseRecognitionExtraFields.coarseConfidenceLevel);
         config->phrases[i].num_levels = 0;
         jobjectArray jConfidenceLevels = (jobjectArray)env->GetObjectField(jPhrase,
                                                 gKeyphraseRecognitionExtraFields.confidenceLevels);
         if (jConfidenceLevels != NULL) {
             config->phrases[i].num_levels = env->GetArrayLength(jConfidenceLevels);
         }
-        ALOGV("startRecognition phrase %d num_levels %d", i, config->phrases[i].num_levels);
+        ALOGV("startRecognition phrase %zu num_levels %d", i, config->phrases[i].num_levels);
         for (size_t j = 0; j < config->phrases[i].num_levels; j++) {
             jobject jConfidenceLevel = env->GetObjectArrayElement(jConfidenceLevels, j);
             config->phrases[i].levels[j].user_id = env->GetIntField(jConfidenceLevel,
@@ -655,7 +741,7 @@
                                                           gConfidenceLevelFields.confidenceLevel);
             env->DeleteLocalRef(jConfidenceLevel);
         }
-        ALOGV("startRecognition phrases %d", i);
+        ALOGV("startRecognition phrases %zu", i);
         env->DeleteLocalRef(jConfidenceLevels);
         env->DeleteLocalRef(jPhrase);
     }
@@ -734,11 +820,12 @@
     jclass modulePropertiesClass = env->FindClass(kModulePropertiesClassPathName);
     gModulePropertiesClass = (jclass) env->NewGlobalRef(modulePropertiesClass);
     gModulePropertiesCstor = env->GetMethodID(modulePropertiesClass, "<init>",
-                              "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIZIZI)V");
+                              "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIZIZIZ)V");
 
     jclass soundModelClass = env->FindClass(kSoundModelClassPathName);
     gSoundModelClass = (jclass) env->NewGlobalRef(soundModelClass);
     gSoundModelFields.uuid = env->GetFieldID(soundModelClass, "uuid", "Ljava/util/UUID;");
+    gSoundModelFields.vendorUuid = env->GetFieldID(soundModelClass, "vendorUuid", "Ljava/util/UUID;");
     gSoundModelFields.data = env->GetFieldID(soundModelClass, "data", "[B");
 
     jclass keyphraseClass = env->FindClass(kKeyphraseClassPathName);
@@ -759,12 +846,12 @@
     jclass recognitionEventClass = env->FindClass(kRecognitionEventClassPathName);
     gRecognitionEventClass = (jclass) env->NewGlobalRef(recognitionEventClass);
     gRecognitionEventCstor = env->GetMethodID(recognitionEventClass, "<init>",
-                                              "(IIZIII[B)V");
+                                              "(IIZIIIZLandroid/media/AudioFormat;[B)V");
 
     jclass keyphraseRecognitionEventClass = env->FindClass(kKeyphraseRecognitionEventClassPathName);
     gKeyphraseRecognitionEventClass = (jclass) env->NewGlobalRef(keyphraseRecognitionEventClass);
     gKeyphraseRecognitionEventCstor = env->GetMethodID(keyphraseRecognitionEventClass, "<init>",
-              "(IIZIII[BZ[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;)V");
+              "(IIZIIIZLandroid/media/AudioFormat;[B[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;)V");
 
 
     jclass keyRecognitionConfigClass = env->FindClass(kRecognitionConfigClassPathName);
@@ -782,9 +869,12 @@
     jclass keyphraseRecognitionExtraClass = env->FindClass(kKeyphraseRecognitionExtraClassPathName);
     gKeyphraseRecognitionExtraClass = (jclass) env->NewGlobalRef(keyphraseRecognitionExtraClass);
     gKeyphraseRecognitionExtraCstor = env->GetMethodID(keyphraseRecognitionExtraClass, "<init>",
-                           "(II[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;)V");
+                           "(III[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;)V");
     gKeyphraseRecognitionExtraFields.id = env->GetFieldID(gKeyphraseRecognitionExtraClass, "id", "I");
-    gKeyphraseRecognitionExtraFields.recognitionModes = env->GetFieldID(gKeyphraseRecognitionExtraClass, "recognitionModes", "I");
+    gKeyphraseRecognitionExtraFields.recognitionModes = env->GetFieldID(gKeyphraseRecognitionExtraClass,
+                                                                        "recognitionModes", "I");
+    gKeyphraseRecognitionExtraFields.coarseConfidenceLevel = env->GetFieldID(gKeyphraseRecognitionExtraClass,
+                                                                        "coarseConfidenceLevel", "I");
     gKeyphraseRecognitionExtraFields.confidenceLevels = env->GetFieldID(gKeyphraseRecognitionExtraClass,
                                              "confidenceLevels",
                                              "[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;");
@@ -796,6 +886,16 @@
     gConfidenceLevelFields.confidenceLevel = env->GetFieldID(confidenceLevelClass,
                                                              "confidenceLevel", "I");
 
+    jclass audioFormatClass = env->FindClass(kAudioFormatClassPathName);
+    gAudioFormatClass = (jclass) env->NewGlobalRef(audioFormatClass);
+    gAudioFormatCstor = env->GetMethodID(audioFormatClass, "<init>", "(III)V");
+
+    jclass soundModelEventClass = env->FindClass(kSoundModelEventClassPathName);
+    gSoundModelEventClass = (jclass) env->NewGlobalRef(soundModelEventClass);
+    gSoundModelEventCstor = env->GetMethodID(soundModelEventClass, "<init>",
+                                              "(II[B)V");
+
+
     int status = AndroidRuntime::registerNativeMethods(env,
                 kSoundTriggerClassPathName, gMethods, NELEM(gMethods));
 
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index f9da127..33bb90bc 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -1293,6 +1293,12 @@
     AudioSystem::setAudioPortCallback(callback);
 }
 
+static jint
+android_media_AudioSystem_getAudioHwSyncForSession(JNIEnv *env, jobject thiz, jint sessionId)
+{
+    return (jint)AudioSystem::getAudioHwSyncForSession((audio_session_t)sessionId);
+}
+
 // ----------------------------------------------------------------------------
 
 static JNINativeMethod gMethods[] = {
@@ -1332,6 +1338,8 @@
                                                 (void *)android_media_AudioSystem_listAudioPatches},
     {"setAudioPortConfig",   "(Landroid/media/AudioPortConfig;)I",
                                             (void *)android_media_AudioSystem_setAudioPortConfig},
+    {"getAudioHwSyncForSession", "(I)I",
+                                    (void *)android_media_AudioSystem_getAudioHwSyncForSession},
 };
 
 
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index d82fc96..81e887d 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -179,7 +179,10 @@
     env->ExceptionClear();
 
     jstring tagstr = env->NewStringUTF(LOG_TAG);
-    jstring msgstr = env->NewStringUTF(msg);
+    jstring msgstr = NULL;
+    if (tagstr != NULL) {
+        msgstr = env->NewStringUTF(msg);
+    }
 
     if ((tagstr == NULL) || (msgstr == NULL)) {
         env->ExceptionClear();      /* assume exception (OOM?) was thrown */
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index ce76b26..afcfaf6 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -348,7 +348,12 @@
 
     DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
     Paint* paint = reinterpret_cast<Paint*>(paintPtr);
-    renderer->drawBitmap(bitmap, left, top, paint);
+
+    // apply transform directly to canvas, so it affects shaders correctly
+    renderer->save(SkCanvas::kMatrix_SaveFlag);
+    renderer->translate(left, top);
+    renderer->drawBitmap(bitmap, paint);
+    renderer->restore();
 }
 
 static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz,
@@ -375,7 +380,12 @@
     DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
     SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
     Paint* paint = reinterpret_cast<Paint*>(paintPtr);
-    renderer->drawBitmap(bitmap, *matrix, paint);
+
+    // apply transform directly to canvas, so it affects shaders correctly
+    renderer->save(SkCanvas::kMatrix_SaveFlag);
+    renderer->concatMatrix(*matrix);
+    renderer->drawBitmap(bitmap, paint);
+    renderer->restore();
 }
 
 static void android_view_GLES20Canvas_drawBitmapData(JNIEnv* env, jobject clazz,
@@ -399,7 +409,12 @@
 
     DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
     Paint* paint = reinterpret_cast<Paint*>(paintPtr);
-    renderer->drawBitmapData(bitmap, left, top, paint);
+
+    // apply transform directly to canvas, so it affects shaders correctly
+    renderer->save(SkCanvas::kMatrix_SaveFlag);
+    renderer->translate(left, top);
+    renderer->drawBitmapData(bitmap, paint);
+    renderer->restore();
 
     // Note - bitmap isn't deleted as DisplayListRenderer owns it now
 }
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 9783e91..3fb084a 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -369,6 +369,13 @@
     SurfaceComposerClient::setDisplayProjection(token, orientation, layerStackRect, displayRect);
 }
 
+static void nativeSetDisplaySize(JNIEnv* env, jclass clazz,
+        jobject tokenObj, jint width, jint height) {
+    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
+    if (token == NULL) return;
+    SurfaceComposerClient::setDisplaySize(token, width, height);
+}
+
 static jobjectArray nativeGetDisplayConfigs(JNIEnv* env, jclass clazz,
         jobject tokenObj) {
     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
@@ -620,6 +627,8 @@
             (void*)nativeSetDisplayLayerStack },
     {"nativeSetDisplayProjection", "(Landroid/os/IBinder;IIIIIIIII)V",
             (void*)nativeSetDisplayProjection },
+    {"nativeSetDisplaySize", "(Landroid/os/IBinder;II)V",
+            (void*)nativeSetDisplaySize },
     {"nativeGetDisplayConfigs", "(Landroid/os/IBinder;)[Landroid/view/SurfaceControl$PhysicalDisplayInfo;",
             (void*)nativeGetDisplayConfigs },
     {"nativeGetActiveConfig", "(Landroid/os/IBinder;)I",
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d7aea39..d57a8b8 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -75,6 +75,7 @@
     <protected-broadcast android:name="android.intent.action.USER_SWITCHED" />
 
     <protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGED" />
+    <protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGING" />
 
     <protected-broadcast android:name="android.app.action.ENTER_CAR_MODE" />
     <protected-broadcast android:name="android.app.action.EXIT_CAR_MODE" />
@@ -879,6 +880,15 @@
         android:description="@string/permdesc_bluetoothPriv"
         android:label="@string/permlab_bluetoothPriv" />
 
+    <!-- Control access to email providers exclusively for Bluetooth
+         @hide
+    -->
+    <permission android:name="android.permission.BLUETOOTH_MAP"
+        android:permissionGroup="android.permission-group.BLUETOOTH_NETWORK"
+        android:protectionLevel="signature"
+        android:description="@string/permdesc_bluetoothMap"
+        android:label="@string/permlab_bluetoothMap" />
+
     <!-- Allows bluetooth stack to access files
          @hide This should only be used by Bluetooth apk.
     -->
@@ -2811,7 +2821,13 @@
          @hide This is not a third-party API (intended for system apps). -->
     <permission android:name="android.permission.READ_INSTALL_SESSIONS"
         android:label="@string/permlab_readInstallSessions"
-        android:description="@string/permdesc_readInstallSessions"
+        android:description="@string/permdesc_readInstallSessions" />
+
+    <!-- @SystemApi Allows an application to remove DRM certificates
+         @hide This is not a third-party API (intended for system apps). -->
+    <permission android:name="android.permission.REMOVE_DRM_CERTIFICATES"
+        android:label="@string/permlab_removeDrmCertificates"
+        android:description="@string/permdesc_removeDrmCertificates"
         android:protectionLevel="signature|system" />
 
     <!-- The system process is explicitly the only one allowed to launch the
diff --git a/core/res/res/anim/progress_indeterminate_horizontal_rect1_scale.xml b/core/res/res/anim/progress_indeterminate_horizontal_rect1_scale.xml
new file mode 100644
index 0000000..7c782a6
--- /dev/null
+++ b/core/res/res/anim/progress_indeterminate_horizontal_rect1_scale.xml
@@ -0,0 +1,45 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <objectAnimator
+        android:duration="2016"
+        android:pathData="M 0.1 1 l 0 0 l 0.00882427215576 0 l 0.00982859611511 0
+l 0.01086503982544 0 l 0.01193084716797 0 l 0.0130220413208 0 l 0.01413340568542 0
+l 0.01525821685791 0 l 0.01638801574707 0 l 0.01751272201538 0 l 0.01862035751343 0
+l 0.01969732284546 0 l 0.02072854995728 0 l 0.02169786453247 0 l 0.02258871078491 0
+l 0.02338474273682 0 l 0.02407070159912 0 l 0.02463348388672 0 l 0.0250626373291 0
+l 0.02535140991211 0 l 0.02549694061279 0 l 0.02550048828125 0 l 0.02536708831787 0
+l 0.02510528564453 0 l 0.02472625732422 0 l 0.0242431640625 0 l 0.02367015838623 0
+l 0.02302188873291 0 l 0.02231246948242 0 l 0.02155555725098 0 l 0.02076324462891 0
+l 0.01994682312012 0 l 0.01911575317383 0 l 0.01827827453613 0 l 0.01732414245605 0
+l 0.01522109985352 0 l 0.01262580871582 0 l 0.00973388671875 0 l 0.00647575378418 0
+l 0.0027661895752 0 l -0.00149223327637 0 l -0.00639404296875 0 l -0.01199066162109 0
+l -0.01820671081543 0 l -0.02470901489258 0 l -0.03080444335937 0 l -0.0355574798584 0
+l -0.03823974609375 0 l -0.03876884460449 0 l -0.03766212463379 0 l -0.03562252044678 0
+l -0.03321434020996 0 l -0.03078151702881 0 l -0.02849582672119 0 l -0.02642543792725 0
+l -0.02458423614502 0 l -0.02296115875244 0 l -0.02153518676758 0 l -0.02028285980225 0
+l -0.01918155670166 0 l -0.01821084976196 0 l -0.01735286712646 0 l -0.01659231185913 0
+l -0.01591604232788 0 l -0.0153129196167 0 l -0.01477350234985 0 l -0.01413362503052 0
+l -0.01339265823364 0 l -0.01270362854004 0 l -0.01206108093262 0 l -0.01146033287048 0
+l -0.01089729309082 0 l -0.01036835670471 0 l -0.00987038612366 0 l -0.00940062522888 0
+l -0.00895661354065 0 l -0.00853617668152 0"
+        android:propertyXName="scaleX"
+        android:repeatCount="infinite" />
+
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/progress_indeterminate_horizontal_rect1_translate.xml b/core/res/res/anim/progress_indeterminate_horizontal_rect1_translate.xml
new file mode 100644
index 0000000..c26bb5d
--- /dev/null
+++ b/core/res/res/anim/progress_indeterminate_horizontal_rect1_translate.xml
@@ -0,0 +1,50 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <objectAnimator
+        android:duration="2016"
+        android:pathData="M -522.599975585938 0 l 0 0 l 0.12939453125 0
+l 0.33831787109375 0 l 0.55450439453125 0 l 0.7708740234375 0 l 0.98065185546875 0
+l 1.1964111328125 0 l 1.41351318359375 0 l 1.63153076171875 0 l 1.85052490234375 0
+l 2.07052612304688 0 l 2.29080200195312 0 l 2.51150512695312 0 l 2.73260498046875 0
+l 2.95355224609375 0 l 3.17404174804688 0 l 3.39422607421875 0 l 3.61355590820312 0
+l 3.83163452148438 0 l 4.04849243164062 0 l 4.263671875 0 l 5.74725341796875 0
+l 6.1026611328125 0 l 6.45980834960938 0 l 6.81781005859375 0 l 7.17654418945312 0
+l 7.53366088867188 0 l 7.88861083984375 0 l 8.23974609375 0 l 8.58447265625 0
+l 8.92156982421875 0 l 9.24810791015625 0 l 9.56137084960938 0 l 9.85906982421875 0
+l 10.1377868652344 0 l 10.3955688476562 0 l 10.6287536621094 0 l 10.8357238769531 0
+l 11.0149230957031 0 l 11.1639709472656 0 l 11.2832336425781 0 l 11.3713989257812 0
+l 11.4301147460938 0 l 11.4596557617188 0 l 11.4611053466797 0 l 11.4369049072266 0
+l 11.3887786865234 0 l 11.3183441162109 0 l 11.2276000976562 0 l 11.1185607910156 0
+l 10.9933776855469 0 l 10.8534698486328 0 l 10.6995391845703 0 l 10.533935546875 0
+l 10.3744659423828 0 l 10.3707733154297 0 l 10.4309463500977 0 l 10.5275726318359 0
+l 10.671501159668 0 l 10.8763961791992 0 l 11.1566543579102 0 l 11.5270767211914 0
+l 11.9947967529297 0 l 12.5502433776855 0 l 13.1453399658203 0 l 13.680793762207 0
+l 14.0223298072815 0 l 14.0650296211243 0 l 13.798041343689 0 l 13.2949924468994 0
+l 12.6584892272949 0 l 11.9693031311035 0 l 11.2772979736328 0 l 10.607666015625 0
+l 9.97052764892578 0 l 9.36723327636719 0 l 8.79751586914062 0 l 8.25792694091797 0
+l 7.74495697021484 0 l 7.25632476806641 0 l 6.78855895996094 0 l 6.33934020996094 0
+l 5.9071044921875 0 l 5.48941040039062 0 l 5.08502197265625 0 l 4.69291687011719 0
+l 4.33430480957031 0 l 4.00733947753906 0 l 3.68829345703125 0 l 3.37684631347656 0
+l 3.07246398925781 0 l 2.77439880371094 0 l 2.48252868652344 0 l 2.20101928710938 0
+l 1.91748046875 0 l 1.63726806640625 0 l 1.36772155761719 0"
+        android:propertyXName="translateX"
+        android:repeatCount="infinite" />
+
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/progress_indeterminate_horizontal_rect2_scale.xml b/core/res/res/anim/progress_indeterminate_horizontal_rect2_scale.xml
new file mode 100644
index 0000000..ef1677d
--- /dev/null
+++ b/core/res/res/anim/progress_indeterminate_horizontal_rect2_scale.xml
@@ -0,0 +1,56 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <objectAnimator
+        android:duration="2016"
+        android:pathData="M 0.1 1 l 0.00930031776428 0 l 0.01123028755188 0
+l 0.01313143730164 0 l 0.01497107505798 0 l 0.01671510696411 0 l 0.01833034515381 0
+l 0.01978672027588 0 l 0.02105976104736 0 l 0.02213228225708 0 l 0.02299520492554 0
+l 0.02364795684814 0 l 0.02409727096558 0 l 0.02435619354248 0 l 0.02444213867188 0
+l 0.02437515258789 0 l 0.02417644500732 0 l 0.02386695861816 0 l 0.02346652984619 0
+l 0.02299335479736 0 l 0.0224634552002 0 l 0.02189086914062 0 l 0.02128746032715 0
+l 0.02066318511963 0 l 0.02002624511719 0 l 0.01938335418701 0 l 0.01873977661133 0
+l 0.01809989929199 0 l 0.01746696472168 0 l 0.01684349060059 0 l 0.01623161315918 0
+l 0.0156324005127 0 l 0.0150471496582 0 l 0.01447631835938 0 l 0.01392051696777 0
+l 0.01337966918945 0 l 0.0128540802002 0 l 0.01234344482422 0 l 0.01184753417969 0
+l 0.0113663482666 0 l 0.01089920043945 0 l 0.01044593811035 0 l 0.00998542785645 0
+l 0.00933837890625 0 l 0.00863349914551 0 l 0.00791206359863 0 l 0.00717010498047 0
+l 0.00640274047852 0 l 0.00560478210449 0 l 0.00477012634277 0 l 0.00389221191406 0
+l 0.00296325683594 0 l 0.0019751739502 0 l 0.00091903686523 0 l -0.00021408081055 0
+l -0.00143287658691 0 l -0.00274444580078 0 l -0.00415267944336 0 l -0.00565589904785 0
+l -0.00724327087402 0 l -0.00889205932617 0 l -0.01056480407715 0 l -0.01220878601074 0
+l -0.01376045227051 0 l -0.01515449523926 0 l -0.01633560180664 0 l -0.01726905822754 0
+l -0.01794639587402 0 l -0.0183829498291 0 l -0.01861137390137 0 l -0.01867179870605 0
+l -0.01860504150391 0 l -0.01844764709473 0 l -0.01822959899902 0 l -0.01797431945801 0
+l -0.0176993560791 0 l -0.0174169921875 0 l -0.01713603973389 0 l -0.01686214447021 0
+l -0.01651359558105 0 l -0.01609485626221 0 l -0.01569358825684 0 l -0.01531024932861 0
+l -0.0149446105957 0 l -0.01459632873535 0 l -0.01426464080811 0 l -0.0139489364624 0
+l -0.01364833831787 0 l -0.01336200714111 0 l -0.01308917999268 0 l -0.01282897949219 0
+l -0.01258075714111 0 l -0.01234363555908 0 l -0.01211700439453 0 l -0.01190029144287 0
+l -0.01169273376465 0 l -0.01149394989014 0 l -0.01130325317383 0 l -0.01112024307251 0
+l -0.01094444274902 0 l -0.01077545166016 0 l -0.0106128692627 0 l -0.01045631408691 0
+l -0.01030544281006 0 l -0.01016000747681 0 l -0.01001962661743 0 l -0.0098840713501 0
+l -0.00975311279297 0 l -0.00962644577026 0 l -0.00950393676758 0 l -0.00938529968262 0
+l -0.00927038192749 0 l -0.00915899276733 0 l -0.00905097961426 0 l -0.00894614219666 0
+l -0.00884438514709 0 l -0.00874552726746 0 l -0.00864946365356 0 l -0.00855606079102 0
+l -0.00846519470215 0 l -0.00837676048279 0 "
+        android:propertyXName="scaleX"
+        android:repeatCount="infinite" />
+
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/progress_indeterminate_horizontal_rect2_translate.xml b/core/res/res/anim/progress_indeterminate_horizontal_rect2_translate.xml
new file mode 100644
index 0000000..f4cf83d
--- /dev/null
+++ b/core/res/res/anim/progress_indeterminate_horizontal_rect2_translate.xml
@@ -0,0 +1,56 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <objectAnimator
+        android:duration="2016"
+        android:pathData="M -197.600006103516 0 l 1.42625427246094 0
+l 1.80754089355469 0 l 2.18778991699219 0 l 2.56109619140625 0 l 2.91810607910156 0
+l 3.25482177734375 0 l 3.57159423828125 0 l 3.862548828125 0 l 4.12493896484375 0
+l 4.35758972167969 0 l 4.56034851074219 0 l 4.73426818847656 0 l 4.88090515136719 0
+l 5.00271606445312 0 l 5.10273742675781 0 l 5.18400573730469 0 l 5.24911499023438 0
+l 5.30097961425781 0 l 5.34226226806641 0 l 5.37535095214844 0 l 5.40180206298828 0
+l 5.42322540283203 0 l 5.44123077392578 0 l 5.45704650878906 0 l 5.47099304199219 0
+l 5.48395538330078 0 l 5.4967041015625 0 l 5.50949859619141 0 l 5.52214813232422 0
+l 5.53528594970703 0 l 5.54912567138672 0 l 5.56306457519531 0 l 5.57742691040039 0
+l 5.59244155883789 0 l 5.60744094848633 0 l 5.62243270874023 0 l 5.6376781463623 0
+l 5.65262794494629 0 l 5.66689777374268 0 l 5.68069934844971 0 l 5.69401162862778 0
+l 5.70898681879044 0 l 5.75169992446899 0 l 5.80327129364014 0 l 5.85710144042969 0
+l 5.91399765014648 0 l 5.97450065612793 0 l 6.03849411010742 0 l 6.10729217529297 0
+l 6.18125534057617 0 l 6.26116561889648 0 l 6.34840393066406 0 l 6.44406127929688 0
+l 6.54866790771484 0 l 6.66371917724609 0 l 6.79020690917969 0 l 6.92859649658203 0
+l 7.07807159423828 0 l 7.23712158203125 0 l 7.40253448486328 0 l 7.56884765625 0
+l 7.72840881347656 0 l 7.87199401855469 0 l 7.98992919921875 0 l 8.07417297363281 0
+l 8.12013244628906 0 l 8.12655639648438 0 l 8.09510803222656 0 l 8.03091430664062 0
+l 7.93995666503906 0 l 7.827880859375 0 l 7.69976806640625 0 l 7.56065368652344 0
+l 7.41322326660156 0 l 7.26063537597656 0 l 7.10470581054688 0 l 6.94624328613281 0
+l 6.78694152832031 0 l 6.6390380859375 0 l 6.50302124023438 0 l 6.36688232421875 0
+l 6.23043823242188 0 l 6.09356689453125 0 l 5.95706176757812 0 l 5.82064819335938 0
+l 5.6839599609375 0 l 5.5477294921875 0 l 5.41143798828125 0 l 5.27532958984375 0
+l 5.13922119140625 0 l 5.00347900390625 0 l 4.8680419921875 0 l 4.73251342773438 0
+l 4.59732055664062 0 l 4.46258544921875 0 l 4.328125 0 l 4.1937255859375 0
+l 4.0599365234375 0 l 3.92672729492188 0 l 3.79376220703125 0 l 3.66119384765625 0
+l 3.52935791015625 0 l 3.398193359375 0 l 3.26748657226562 0 l 3.13726806640625 0
+l 3.00796508789062 0 l 2.87939453125 0 l 2.7515869140625 0 l 2.62445068359375 0
+l 2.49810791015625 0 l 2.3726806640625 0 l 2.2481689453125 0 l 2.12457275390625 0
+l 2.00173950195312 0 l 1.87997436523438 0 l 1.7618408203125 0 l 1.64154052734375 0
+l 1.51962280273438 0 l 1.40017700195312 0 l 1.28421020507812 0 "
+        android:propertyXName="translateX"
+        android:repeatCount="infinite" />
+
+</set>
\ No newline at end of file
diff --git a/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png
deleted file mode 100644
index 8148ab8..0000000
--- a/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_tether_wifi.png b/core/res/res/drawable-hdpi/stat_sys_tether_wifi.png
deleted file mode 100644
index 7d4df50..0000000
--- a/core/res/res/drawable-hdpi/stat_sys_tether_wifi.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-ldpi/stat_notify_wifi_in_range.png
deleted file mode 100644
index 1ff50ea..0000000
--- a/core/res/res/drawable-ldpi/stat_notify_wifi_in_range.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_tether_wifi.png b/core/res/res/drawable-ldpi/stat_sys_tether_wifi.png
deleted file mode 100644
index b4b3cfd..0000000
--- a/core/res/res/drawable-ldpi/stat_sys_tether_wifi.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png
deleted file mode 100644
index b7e2a6a..0000000
--- a/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_tether_wifi.png b/core/res/res/drawable-mdpi/stat_sys_tether_wifi.png
deleted file mode 100644
index 869ad35..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_tether_wifi.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-xhdpi/stat_notify_wifi_in_range.png
deleted file mode 100644
index 0dbae57..0000000
--- a/core/res/res/drawable-xhdpi/stat_notify_wifi_in_range.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_tether_wifi.png b/core/res/res/drawable-xhdpi/stat_sys_tether_wifi.png
deleted file mode 100644
index dc48646..0000000
--- a/core/res/res/drawable-xhdpi/stat_sys_tether_wifi.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-xxhdpi/stat_notify_wifi_in_range.png
deleted file mode 100644
index 47e74fb..0000000
--- a/core/res/res/drawable-xxhdpi/stat_notify_wifi_in_range.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_tether_wifi.png b/core/res/res/drawable-xxhdpi/stat_sys_tether_wifi.png
deleted file mode 100644
index da44e6a..0000000
--- a/core/res/res/drawable-xxhdpi/stat_sys_tether_wifi.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/progress_indeterminate_horizontal_material.xml b/core/res/res/drawable/progress_indeterminate_horizontal_material.xml
new file mode 100644
index 0000000..4fc68ce
--- /dev/null
+++ b/core/res/res/drawable/progress_indeterminate_horizontal_material.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/vector_drawable_progress_indeterminate_horizontal" >
+
+    <target
+        android:name="path1"
+        android:animation="@anim/progress_indeterminate_horizontal_rect1_translate" />
+    <target
+        android:name="path1"
+        android:animation="@anim/progress_indeterminate_horizontal_rect1_scale" />
+
+    <target
+        android:name="path2"
+        android:animation="@anim/progress_indeterminate_horizontal_rect2_translate" />
+    <target
+        android:name="path2"
+        android:animation="@anim/progress_indeterminate_horizontal_rect2_scale" />
+</animated-vector>
diff --git a/core/res/res/drawable/stat_notify_wifi_in_range.xml b/core/res/res/drawable/stat_notify_wifi_in_range.xml
new file mode 100644
index 0000000..9a5407d
--- /dev/null
+++ b/core/res/res/drawable/stat_notify_wifi_in_range.xml
@@ -0,0 +1,27 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="26.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="26.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#4DFFFFFF"
+        android:pathData="M19.100000,14.000000l-3.400000,0.000000l0.000000,-1.500000c0.000000,-1.800000 0.800000,-2.800000 1.500000,-3.400000C18.100000,8.300000 19.200001,8.000000 20.600000,8.000000c1.200000,0.000000 2.300000,0.300000 3.100000,0.800000l1.900000,-2.300000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000l0.000000,0.000000l0.000000,0.000000l0.000000,0.000000l0.000000,0.000000l6.500000,-8.100000L19.100000,14.000000z"/>
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M19.500000,17.799999c0.000000,-0.800000 0.100000,-1.300000 0.200000,-1.600000c0.200000,-0.300000 0.500000,-0.700000 1.100000,-1.200000c0.400000,-0.400000 0.700000,-0.800000 1.000000,-1.100000s0.400000,-0.800000 0.400000,-1.200000c0.000000,-0.500000 -0.100000,-0.900000 -0.400000,-1.200000c-0.300000,-0.300000 -0.700000,-0.400000 -1.200000,-0.400000c-0.400000,0.000000 -0.800000,0.100000 -1.100000,0.300000c-0.300000,0.200000 -0.400000,0.600000 -0.400000,1.100000l-1.900000,0.000000c0.000000,-1.000000 0.300000,-1.700000 1.000000,-2.200000c0.600000,-0.500000 1.500000,-0.800000 2.500000,-0.800000c1.100000,0.000000 2.000000,0.300000 2.600000,0.800000c0.600000,0.500000 0.900000,1.300000 0.900000,2.300000c0.000000,0.700000 -0.200000,1.300000 -0.600000,1.800000c-0.400000,0.600000 -0.900000,1.100000 -1.500000,1.600000c-0.300000,0.300000 -0.500000,0.500000 -0.600000,0.700000c-0.100000,0.200000 -0.100000,0.600000 -0.100000,1.000000L19.500000,17.700001zM21.400000,21.000000l-1.900000,0.000000l0.000000,-1.800000l1.900000,0.000000L21.400000,21.000000z"/>
+</vector>
diff --git a/core/res/res/drawable/stat_sys_tether_wifi.xml b/core/res/res/drawable/stat_sys_tether_wifi.xml
new file mode 100644
index 0000000..a816db8
--- /dev/null
+++ b/core/res/res/drawable/stat_sys_tether_wifi.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="26.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="26.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+</vector>
diff --git a/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml b/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml
new file mode 100644
index 0000000..0cc7202
--- /dev/null
+++ b/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml
@@ -0,0 +1,60 @@
+<!--
+ 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.
+-->
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="4dp"
+    android:viewportHeight="4"
+    android:viewportWidth="360"
+    android:width="360dp" >
+
+    <group
+        android:name="linear_indeterminate"
+        android:translateX="180.0"
+        android:translateY="0.0" >
+        <group
+            android:name="path1"
+            android:scaleX="0.1"
+            android:translateX="-522.59" >
+            <path
+                android:name="rect1"
+                android:fillColor="?attr/colorControlActivated"
+                android:pathData="m 0 1.6 l 288 0 l 0 0.8 l -288 0 z" />
+        </group>
+        <group
+            android:name="path2"
+            android:scaleX="0.1"
+            android:translateX="-197.6" >
+            <path
+                android:name="rect2"
+                android:fillColor="?attr/colorControlActivated"
+                android:pathData="m 0 1.6 l 288 0 l 0 0.8 l -288 0 z" />
+        </group>
+    </group>
+</vector>
\ No newline at end of file
diff --git a/core/res/res/layout/input_method_switch_dialog_title.xml b/core/res/res/layout/input_method_switch_dialog_title.xml
index e11a523..d498d23 100644
--- a/core/res/res/layout/input_method_switch_dialog_title.xml
+++ b/core/res/res/layout/input_method_switch_dialog_title.xml
@@ -33,7 +33,7 @@
 
         <com.android.internal.widget.DialogTitle
             android:id="@+id/alertTitle"
-            style="@android:style/DialogWindowTitle.Holo"
+            style="@android:style/DialogWindowTitle.DeviceDefault"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:ellipsize="end"
@@ -49,11 +49,6 @@
         android:layout_height="wrap_content"
         android:orientation="vertical" >
 
-        <View
-            android:layout_width="match_parent"
-            android:layout_height="2dip"
-            android:background="@android:color/holo_blue_light" />
-
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
@@ -97,12 +92,10 @@
                 android:layout_gravity="center_vertical"
                 android:layout_marginEnd="12dip" />
         </LinearLayout>
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="1dp"
+            android:background="?android:attr/listDividerAlertDialog" />
     </LinearLayout>
-
-    <View
-        android:id="@+id/titleDivider"
-        android:layout_width="match_parent"
-        android:layout_height="2dip"
-        android:background="@android:drawable/divider_horizontal_dark" />
-
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/core/res/res/layout/input_method_switch_item.xml b/core/res/res/layout/input_method_switch_item.xml
new file mode 100644
index 0000000..cfa8b31
--- /dev/null
+++ b/core/res/res/layout/input_method_switch_item.xml
@@ -0,0 +1,63 @@
+<?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:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    android:gravity="center_vertical"
+    android:paddingStart="16dip"
+    android:paddingEnd="12dip"
+    android:minHeight="?attr/listPreferredItemHeightSmall"
+    android:background="@color/transparent">
+
+    <RadioButton
+        android:id="@+id/radio"
+        android:layout_width="35dip"
+        android:layout_height="wrap_content"
+        android:paddingEnd="12dip"
+        android:gravity="center_vertical"
+        android:focusable="false"
+        android:clickable="false" />
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:orientation="vertical"
+        android:gravity="center_vertical">
+
+        <TextView android:id="@android:id/text1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?attr/textAppearanceListItem"
+            android:textColor="?attr/textColorAlertDialogListItem"
+            android:gravity="center_vertical|start"
+            android:singleLine="true"
+            android:ellipsize="marquee" />
+
+        <TextView android:id="@android:id/text2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?attr/textAppearanceListItemSecondary"
+            android:textColor="?attr/textColorAlertDialogListItem"
+            android:gravity="center_vertical|start"
+            android:singleLine="true"
+            android:ellipsize="marquee" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/core/res/res/layout/preference_widget_switch.xml b/core/res/res/layout/preference_widget_switch.xml
index 04a310b..7395ff2 100644
--- a/core/res/res/layout/preference_widget_switch.xml
+++ b/core/res/res/layout/preference_widget_switch.xml
@@ -20,6 +20,5 @@
     android:id="@+android:id/switchWidget"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:padding="16dip"
     android:focusable="false"
     android:background="@null" />
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index f1d2d38..a287f6b 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Laat \'n program toe om DRM-sertifikate op te stel en te gebruik. Behoort nooit vir normale programme nodig te wees nie."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Ontvang Android Straal-oordragstatus"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Laat hierdie program toe om inligting oor huidige Android Straal-oordragte te ontvang."</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Stel wagwoordreëls"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Beheer lengte en watter karakters wat in die skermontsluit-wagwoorde gebruik word."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitor pogings om skerm te ontsluit"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formaat"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-ontfouter gekoppel"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Raak om USB-ontfouting te deaktiveer."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Kies invoermetode"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Stel invoermetodes op"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fisiese sleutelbord"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardeware"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Kies sleutelborduitleg"</string>
@@ -1384,8 +1390,8 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Laat \'n program toe om keyguard te beheer."</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"Luister na vertrouenstaatveranderinge."</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"Laat \'n program toe om vir veranderinge in vertrouenstaat te luister."</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Voorsien \'n vertroude agent."</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Laat \'n program toe om \'n vertroude agent te voorsien."</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Voorsien \'n vertrouensagent."</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Laat \'n program toe om \'n vertrouensagent te voorsien."</string>
     <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Begin instellingskieslys vir vertrouensagent"</string>
     <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Laat \'n program toe om \'n aktiwiteit te begin wat die vertrouensagentgedrag verander."</string>
     <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Verbind met \'n vertrouensagentdiens"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g> ."</string>
     <string name="owner_name" msgid="2716755460376028154">"Eienaar"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Fout"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Hierdie verandering word nie deur jou administrateur toegelaat nie"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Geen program gevind om hierdie handeling te hanteer nie"</string>
     <string name="revoke" msgid="5404479185228271586">"Herroep"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"ontsluitpatroon"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"wagwoord"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 2bc8f20..9cad23a 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"አንድ መተግበሪያ የDRM የምስክር ወረቀቶችን እንዲሰጥና እንዲጠቀም ያስችላል። ለመደበኛ መተግበሪያዎች በፍጹም አስፈላጊ አይሆንም።"</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"የAndroid Beam ሽግግር ሁኔታን ይቀበሉ"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"ይም መተግበሪያ ስለአሁን የAndroid Beam ሽግግሮች መረጃ እንዲቀበል ይፈቅዳል"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"የይለፍ ቃል ደንቦች አዘጋጅ"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"በማያ-መክፈት የተፈቀዱ የይለፍ ቃል ርዝመት እና ቁምፊዎች ተቆጣጠር።"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"የማሳያ-ክፈት ሙከራዎችን አሳይ"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"ቅርጸት"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB አድስ ተያይዟል"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ማረሚያ ላለማንቃት ዳስስ።"</string>
-    <string name="select_input_method" msgid="4653387336791222978">"የግቤት ስልት ምረጥ"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"የግቤት ስልቶችን አዘጋጅ"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"የሚዳሰስ የቁልፍ ሰሌዳ"</string>
     <string name="hardware" msgid="7517821086888990278">"ሃርድዌር"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"የቁልፍ ሰሌዳ አቀማመጥ ምረጥ"</string>
@@ -1385,9 +1391,9 @@
     <string name="permlab_trust_listener" msgid="1765718054003704476">"የተአማኒነት ሁኔታ ለውጦችን አዳምጥ።"</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"መተግበሪያው በተአማኒነት ሁኔታ ውስጥ ለውጦችን እንዲያዳምጥ ይፈቅዳል።"</string>
     <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"የመታመን ወኪል ያቅርቡ።"</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"አንድ መተግበሪያ የመታመን ወኪል እንዲያቀርብ ይፈቅድለታል።"</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"የሚታመን ወኪል ቅንብሮች ምናሌ ያስጀምራል።"</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"አንድ መተግበሪያ የሚታመነው ወኪል ባህሪ የሚቀይር እንቅስቃሴ እንዲያስጀምር ያስችለዋል።"</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"አንድ መተግበሪያ የተአማኒነት ወኪል እንዲያቀርብ ይፈቅድለታል።"</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"የተአማኒነት ወኪል ቅንብሮች ምናሌ ያስጀምራል።"</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"አንድ መተግበሪያ የተአማኒነት ወኪል ባህሪ የሚቀይር እንቅስቃሴ እንዲያስጀምር ያስችለዋል።"</string>
     <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"ለተአማኒነት ወኪል አገልግሎት ተገዢ አድርግ"</string>
     <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"ለመተግበሪያን የተአማኒነት ወኪል አገልግሎትን እንዲያከብር ይፈቅዳል።"</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"ከዝማኔዎች እና ከመልሶ ማግኛ ስርዓቶች ጋር ይገናኙ"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"የአሁኑ ተጠቃሚ <xliff:g id="NAME">%1$s</xliff:g>።"</string>
     <string name="owner_name" msgid="2716755460376028154">"ባለቤት"</string>
     <string name="error_message_title" msgid="4510373083082500195">"ስህተት"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"ይህ ለውጥ በአስተዳዳሪዎ አይፈቀድም"</string>
     <string name="app_not_found" msgid="3429141853498927379">"ይህን እርምጃ የሚያከናውን ምንም መተግበሪያ አልተገኘም"</string>
     <string name="revoke" msgid="5404479185228271586">"ሻር"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"አይ ኤስ ኦ ኤ0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"ፒን"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"የማስከፈቻ ስርዓተ-ጥለት"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"የይለፍ ቃል"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index a9bef04..c00a883 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"‏للسماح لأحد التطبيقات بتقديم شهادات DRM واستخدامها. لا يجب أن يكون ذلك لازمًا مطلقًا مع التطبيقات العادية."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"‏تلقي حالة نقل شعاع Android"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"‏السماح لهذا التطبيق بتلقي معلومات حول عمليات نقل شعاع Android الحالية"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"تعيين قواعد كلمة المرور"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"يمكنك التحكم في الطول والأحرف المسموح بها في كلمات مرور إلغاء تأمين الشاشة."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"مراقبة محاولات إلغاء قفل الشاشة"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"تنسيق"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏تم توصيل تصحيح أخطاء USB"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"‏المس لتعطيل تصحيح أخطاء USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"اختيار أسلوب الإدخال"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"إعداد أسلوب الإدخال"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"لوحة مفاتيح فعلية"</string>
     <string name="hardware" msgid="7517821086888990278">"أجهزة"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"تحديد تخطيط لوحة مفاتيح"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"المستخدم الحالي <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"المالك"</string>
     <string name="error_message_title" msgid="4510373083082500195">"خطأ"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"لا يسمح المشرف بإجراء هذا التغيير"</string>
     <string name="app_not_found" msgid="3429141853498927379">"لم يتم العثور على تطبيق يمكنه التعامل مع هذا الإجراء."</string>
     <string name="revoke" msgid="5404479185228271586">"إلغاء"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"رقم التعريف الشخصي"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"نقش إلغاء القفل"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"كلمة المرور"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index b0c7b74..3265f76 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Разрешава на приложението да обезпечава и използва сертификатите за управление на цифровите права (DRM). Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Получаване на състоянието на прехвърлянията чрез Android Лъч"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Разрешава на това приложение да получава информация относно текущите прехвърляния чрез Android Лъч"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Задаване на правила за паролата"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролирайте дължината и разрешените знаци за паролите за отключване на екрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Наблюдаване на опитите за отключване на екрана"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Форматиране"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отстраняването на грешки през USB е свързано"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Докоснете, за да деактивирате отстраняването на грешки през USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Избор на метод на въвеждане"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Методи на въвеждане: Настройка"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Физическа клавиатура"</string>
     <string name="hardware" msgid="7517821086888990278">"Хардуер"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Избиране на клавиатурна подредба"</string>
@@ -1384,12 +1390,12 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Разрешава на приложението да контролира функцията за защита на клавишите."</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"Следене за промени в състоянието на надеждност"</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"Разрешава на приложението да следи за промени в състоянието на надеждност."</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Предоставяне на trust agent."</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Разрешава на приложението да предоставя trust agent."</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Предоставяне на надежден агент."</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Разрешава на приложението да предоставя надежден агент."</string>
     <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Стартиране на менюто за настройки за надежден агент."</string>
     <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Разрешава на приложението да стартира активност, която променя поведението на надеждния агент."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Обвързване с услуга за trust agents"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Разрешава на приложението да се обвърже с услуга за trust agents."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Обвързване с услуга за надежден агент"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Разрешава на приложението да се обвърже с услуга за надежден агент."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Взаимодействие със системата за актуализации и възстановяване"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Разрешава на приложението да взаимодейства със системата за възстановяване и системните актуализации."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Създаване на сесии за прожектиране на мултимедия"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Текущ потребител <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Собственик"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Грешка"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Тази промяна не е разрешена от администратора ви"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Няма намерено приложение за извършване на това действие"</string>
     <string name="revoke" msgid="5404479185228271586">"Отмяна"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"ПИН код"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"фигура за отключване"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"парола"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index 1e6dbf4..7269a4c 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"DRM শংসাপত্রগুলির বিধান এবং ব্যবহারা করার অনুমতি দিন৷ সাধারণ অ্যাপ্লিকেশানগুলির জন্য কোনোদিন প্রয়োজন হয় না৷"</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android বীম স্থানান্তর স্থিতি গ্রহণ করুন"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"এই অ্যাপ্লিকেশানকে বর্তমান Android বীম স্থানান্তর সম্বন্ধে তথ্য গ্রহণ করার অনুমিত দেয়"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"পাসওয়ার্ড নিয়মগুলি সেট করে"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"স্ক্রীন আনলক করার পাসওয়ার্ডগুলিতে অনুমতিপ্রাপ্ত অক্ষর এবং দৈর্ঘ্য নিয়ন্ত্রণ করে৷"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"স্ক্রীণ আনলক করার প্রচেষ্টাগুলি নিরীক্ষণ করে"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"ফর্ম্যাট করুন"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ডিবাগিং সংযুক্ত হয়েছে"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ডিবাগিং অক্ষম করতে স্পর্শ করুন৷"</string>
-    <string name="select_input_method" msgid="4653387336791222978">"ইনপুট পদ্ধতি নির্বাচন করুন"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"ইনপুট পদ্ধতিগুলি সেট আপ করুন"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"ফিজিক্যাল কীবোর্ড"</string>
     <string name="hardware" msgid="7517821086888990278">"হার্ডওয়্যার"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"কীবোর্ডের লেআউট নির্বাচন করুন"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"বর্তমান ব্যবহারকারী <xliff:g id="NAME">%1$s</xliff:g>৷"</string>
     <string name="owner_name" msgid="2716755460376028154">"মালিক"</string>
     <string name="error_message_title" msgid="4510373083082500195">"ত্রুটি"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"এই পরিবর্তনটি আপনার প্রশাসক দ্বারা অনুমোদিত নয়"</string>
     <string name="app_not_found" msgid="3429141853498927379">"এই ক্রিয়াটিকে চালনা করার জন্য কোনো অ্যাপ্লিকেশান পাওয়া যায়নি"</string>
     <string name="revoke" msgid="5404479185228271586">"প্রত্যাহার করুন"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"আনলক প্যাটার্ন"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"পাসওয়ার্ড"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 510747f..e920a35 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permet que una aplicació proporcioni i utilitzi certificats de gestió de drets digitals (DRM, Digital Rights Management). No ha de ser mai necessari per a aplicacions normals."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Rep l\'estat de la transferència d\'Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Permet que aquesta aplicació rebi informació sobre les transferències d\'Android Beam actuals."</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir les normes de contrasenya"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controla la longitud i els caràcters permesos a les contrasenyes de desbloqueig de pantalla."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Controlar els intents de desbloqueig de pantalla"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formata"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuració USB activada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca per desactivar la depuració USB"</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Selecciona un mètode d\'entrada"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Configura els mètodes d\'entrada"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Teclat físic"</string>
     <string name="hardware" msgid="7517821086888990278">"Maquinari"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selecciona una disposició de teclat"</string>
@@ -1388,8 +1394,8 @@
     <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Permet que una aplicació proporcioni un agent de confiança."</string>
     <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Iniciar el menú de configuració de l\'agent de confiança"</string>
     <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Permet que una aplicació iniciï una activitat que modifiqui el comportament de l\'agent de confiança."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Enllaçar amb el servei d\'un agent de confiança"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Permet que una aplicació es vinculi amb el servei d\'un agent de confiança."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Enllaçar amb un servei d\'agent de confiança"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Permet que una aplicació es vinculi amb un servei d\'agent de confiança."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Interacciona amb el sistema de recuperació i amb les actualitzacions"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Permet que una aplicació interaccioni amb el sistema de recuperació i amb les actualitzacions del sistema."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Creació de sessions de projecció de fitxers multimèdia"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Usuari actual: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Propietari"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Error"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"L\'administrador no permet aquest canvi."</string>
     <string name="app_not_found" msgid="3429141853498927379">"No s\'ha trobat cap aplicació per processar aquesta acció"</string>
     <string name="revoke" msgid="5404479185228271586">"Revoca"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"patró de desbloqueig"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"contrasenya"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 6af130a..b60ce31 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Umožňuje aplikaci vydávat a používat certifikáty DRM. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Příjem stavu přenosů Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Umožňuje této aplikaci přijímat informace o aktuálních přenosech pomocí technologie Android Beam"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavit pravidla pro heslo"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Řídit délku hesel pro odemčení obrazovky a povolené znaky."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Sledovat pokusy o odemčení obrazovky"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formátovat"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladění přes rozhraní USB připojeno"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotykem zakážete ladění USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Vybrat metodu zadávání"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Nastavit metody zadávání"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fyzická klávesnice"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Výběr rozložení klávesnice"</string>
@@ -1384,12 +1390,12 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Umožňuje aplikaci ovládat zámek obrazovky."</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"Naslouchat změnám stavu důvěryhodnosti"</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"Umožňuje aplikaci naslouchat změnám ve stavu důvěryhodnosti."</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Poskytování zástupce důvěryhodnosti"</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Umožňuje aplikaci poskytnout zástupce důvěryhodnosti."</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Spustit nabídku nastavení agenta důvěryhodnosti"</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Umožňuje aplikaci spustit aktivitu, která změní chování agenta důvěryhodnosti."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Vázat se na službu zástupce důvěryhodnosti"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Umožňuje aplikaci vázat se na službu zástupce důvěryhodnosti."</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Poskytovat agenta důvěry"</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Umožňuje aplikaci poskytnout agent důvěry."</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Spustit nabídku nastavení agenta důvěry"</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Umožňuje aplikaci spustit aktivitu, která změní chování agenta důvěry."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Vázat se na službu agent důvěry"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Umožňuje aplikaci vázat se na službu agent důvěry."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Interakce se systémem aktualizací a obnovení"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Umožňuje aplikaci interakci se systémem obnovení a s aktualizacemi systému."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Vytváření relací promítání médií"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Aktuální uživatel je <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Vlastník"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Chyba"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Administrátor tuto změnu zakázal"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Aplikace potřebná k provedení této akce nebyla nalezena"</string>
     <string name="revoke" msgid="5404479185228271586">"Zrušit"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"bezpečnostní gesto"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"heslo"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 55ee236..1b10b77 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Tillader, at en applikation leverer og anvender DRM-certfikater. Dette bør aldrig være nødvendigt for almindelige apps."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Modtag staus for Android Beam-overførsler"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Tillader, at applikationen modtager oplysninger om aktuelle Android Beam-overførsler"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Indstil regler for adgangskode"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontroller længden samt tilladte tegn i adgangskoder til oplåsning af skærmen."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Overvåg forsøg på oplåsning af skærm"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formater"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-fejlretning er tilsluttet"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Tryk for at deaktivere USB-fejlretning."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Vælg inputmetode"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Konfigurer inputmetoder"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fysisk tastatur"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Vælg tastaturlayout"</string>
@@ -1384,8 +1390,8 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Tillader, at en applikation styrer nøglebeskyttelsen."</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"Registrere ændringer i trust-tilstand."</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"Tillader, at en applikation registrerer ændringer i trust-tilstand."</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Angiv en tillidsagent."</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Tillader, at en applikation angiver en tillidsagent."</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Angiv en trust agent."</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Tillader, at en applikation angiver en trust agent."</string>
     <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Åbn indstillingsmenuen for trust agent."</string>
     <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Tillader, at en app starter en aktivitet, der ændrer adfærden for trust agent."</string>
     <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Knytte sig til en trust agent-tjeneste"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Nuværende bruger <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Ejer"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Fejl"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Din administrator har ikke givet tilladelse til at foretage denne ændring"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Der blev ikke fundet nogen applikation, der kan håndtere denne handling"</string>
     <string name="revoke" msgid="5404479185228271586">"Tilbagekald"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"Pinkode"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"oplåsningsmønster"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"adgangskode"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index aee819d..fa81a74 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Ermöglicht einer App die Bereitstellung und Nutzung von DRM-Zertifikaten. Sollte für normale Apps nie benötigt werden."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Status von Android Beam-Übertragungen erhalten"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Ermöglicht dieser App, Informationen zu aktuellen Android Beam-Übertragungen zu erhalten"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Passwortregeln festlegen"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Zulässige Länge und Zeichen für Passwörter zum Entsperren des Bildschirms festlegen"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Versuche zum Entsperren des Displays überwachen"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Zum Deaktivieren von USB-Debugging berühren"</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Eingabemethode wählen"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Eingabemethoden einrichten"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Physische Tastatur"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Tastaturlayout auswählen"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Aktueller Nutzer <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="owner_name" msgid="2716755460376028154">"Eigentümer"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Fehler"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Ihr Administrator lässt diese Änderung nicht zu."</string>
     <string name="app_not_found" msgid="3429141853498927379">"Für diese Aktion wurde keine App gefunden."</string>
     <string name="revoke" msgid="5404479185228271586">"Aufheben"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"Entsperrungsmuster"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"Passwort"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 70dfd9a..7a56b29 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Επιτρέπει σε μια εφαρμογή να παρέχει και να χρησιμοποιεί πιστοποιητικά DRM. Δεν θα χρειαστεί ποτέ για κανονικές εφαρμογές."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Λήψη κατάστασης μεταφοράς Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Επιτρέπει σε αυτήν την εφαρμογή να λαμβάνει πληροφορίες σχετικά με τις τρέχουσες μεταφορές Android Beam"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Ορισμός κανόνων κωδικού πρόσβασης"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Έλεγχος του μεγέθους και των χαρακτήρων που επιτρέπονται στους κωδικούς πρόσβασης ξεκλειδώματος οθόνης."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Παρακολούθηση προσπαθειών ξεκλειδώματος οθόνης"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Διαμόρφωση"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Συνδέθηκε ο εντοπισμός σφαλμάτων USB"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Αγγίξτε για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Επιλογή μεθόδου εισόδου"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Ρύθμιση μεθόδων εισαγωγής"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Φυσικό πληκτρολόγιο"</string>
     <string name="hardware" msgid="7517821086888990278">"Υλικό"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Επιλογή διάταξης πληκτρολογίου"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Κάτοχος"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Σφάλμα"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Αυτή η αλλαγή δεν επιτρέπεται από το διαχειριστή σας"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Δεν υπάρχει εφαρμογή για τη διαχείριση αυτής της ενέργειας"</string>
     <string name="revoke" msgid="5404479185228271586">"Ανάκληση"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"Αριθμός PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"μοτίβο ξεκλειδώματος"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"κωδικός πρόσβασης"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 8dd9170..01af6a3 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -739,6 +739,10 @@
     <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>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Control the length and the characters allowed in screen-unlock passwords."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitor screen-unlock attempts"</string>
@@ -1339,8 +1343,10 @@
     <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="4653387336791222978">"Choose input method"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Set up input methods"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Physical keyboard"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Select keyboard layout"</string>
@@ -1764,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"unlock pattern"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"password"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 8dd9170..01af6a3 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -739,6 +739,10 @@
     <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>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Control the length and the characters allowed in screen-unlock passwords."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitor screen-unlock attempts"</string>
@@ -1339,8 +1343,10 @@
     <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="4653387336791222978">"Choose input method"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Set up input methods"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Physical keyboard"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Select keyboard layout"</string>
@@ -1764,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"unlock pattern"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"password"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 9c8863f..941309e 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permite que una aplicación proporcione y utilice certificados DRM. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Recibir estado de transferencias de Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Permite que esta aplicación reciba información sobre las transferencias actuales de Android Beam"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Establecer reglas de contraseña"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar la longitud y los caracteres permitidos en las contraseñas para desbloquear la pantalla"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Supervisa los intentos para desbloquear la pantalla"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formato"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración por USB conectada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca para desactivar la depuración por USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Selecciona el método de entrada"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Configurar métodos de introducción"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Teclado físico"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selecciona un diseño de teclado"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="owner_name" msgid="2716755460376028154">"Propietario"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Error"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"El administrador no permite este cambio."</string>
     <string name="app_not_found" msgid="3429141853498927379">"No se encontró una aplicación para manejar esta acción."</string>
     <string name="revoke" msgid="5404479185228271586">"Revocar"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"patrón de desbloqueo"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"contraseña"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index cc6d4f7..95984f4 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permite que una aplicación proporcione y utilice certificados DRM. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Recibir estado de transferencias de Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Permite que esta aplicación reciba información sobre las transferencias actuales de Android Beam"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Establecimiento de reglas de contraseña"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar la longitud y los caracteres permitidos en las contraseñas de bloqueo de pantalla"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Control de intentos de bloqueo de pantalla"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formato"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB habilitada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca para inhabilitar la depuración USB"</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Selecciona un método de entrada"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Configurar métodos de entrada"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Teclado físico"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selecciona un diseño de teclado"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="owner_name" msgid="2716755460376028154">"Propietario"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Error"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"El administrador no permite este cambio"</string>
     <string name="app_not_found" msgid="3429141853498927379">"No se ha encontrado ninguna aplicación que pueda realizar esta acción."</string>
     <string name="revoke" msgid="5404479185228271586">"Revocar"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"patrón de desbloqueo"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"contraseña"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 2ccdab0..f3fe8ca 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Lubab rakendusel ette valmistada ja kasutada DRM-i sertifikaate. Tavarakenduste puhul ei tohiks see vajalik olla."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android Beami ülekande oleku vastuvõtmine"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Lubab rakendusel saada teavet praeguste Android Beami ülekannete kohta"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Parooli reeglite määramine"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrollige ekraaniluku avamise paroolide pikkust ja tähemärke."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Ekraani avamiskatsed"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Vorminda"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-silumine ühendatud"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Puudutage USB-silumise keelamiseks."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Valige sisestusmeetod"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Seadista sisestusmeetodid"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Füüsiline klaviatuur"</string>
     <string name="hardware" msgid="7517821086888990278">"Riistvara"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Klaviatuuri paigutuse valimine"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Praegune kasutaja <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Omanik"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Viga"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Administraator ei luba sellist muudatust teha"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Selle toimingu käsitlemiseks ei leitud ühtegi rakendust"</string>
     <string name="revoke" msgid="5404479185228271586">"Tühista"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN-koodi"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"avamismustrit"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"parooli"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index a01b437..25dbcbd 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"DRM ziurtagiriak hornitzea eta erabiltzea baimentzen die aplikazioei. Aplikazio normalek ez lukete beharko."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Jaso Android Beam transferentzien egoera"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Uneko Android Beam transferentziei buruzko informazioa jasotzea baimentzen die aplikazioei"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Ezarri pasahitzen arauak"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolatu pantaila desblokeatzeko pasahitzen luzera eta onartutako karaktereak."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Kontrolatu pantaila desblokeatzeko saiakerak"</string>
@@ -1319,8 +1323,8 @@
     <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Desaktibatu USB memoria"</string>
     <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Ukitu USB memoria desaktibatzeko."</string>
     <string name="usb_storage_stop_title" msgid="660129851708775853">"USB memoria erabiltzen ari da"</string>
-    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB memoria desaktibatu aurretik, desmuntatu (\"egotzi\") Android USB txartela ordenagailutik."</string>
-    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"USB memoria desaktibatu aurretik, desmuntatu (\"egotzi\") Android SD txartela ordenagailutik."</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB memoria desaktibatu aurretik, desmuntatu (\"kanporatu\") Android USB txartela ordenagailutik."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"USB memoria desaktibatu aurretik, desmuntatu (\"kanporatu\") Android SD txartela ordenagailutik."</string>
     <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Desaktibatu USB memoria"</string>
     <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Arazo bat izan da USB memoria desaktibatzean. Egiaztatu USB ostalaria desmuntatu duzula eta saiatu berriro."</string>
     <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Aktibatu USB memoria"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formateatu"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB arazketa konektatuta"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB arazketa desgaitzeko, ukitu hau."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Aukeratu idazketa-metodoa"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Konfiguratu idazketa-metodoak"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Teklatu fisikoa"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardwarea"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Hautatu teklatuaren diseinua"</string>
@@ -1388,8 +1394,8 @@
     <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Fidagarritasun-agenteak hornitzea baimentzen die aplikazioei."</string>
     <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Abiarazi fidagarritasun-agenteen ezarpenen menua."</string>
     <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Fidagarritasun-agenteen portaera aldatzeko jarduerak abiaraztea baimentzen die aplikazioei."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Lotu konfiantza zehazteko agenteen zerbitzuei"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Konfiantza zehazteko agente baten zerbitzuari lotzea baimentzen die aplikazioei."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Lotu fidagarritasun-agenteen zerbitzu bati"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Fidagarritasun-agenteen zerbitzu bati lotzea baimentzen die aplikazioei."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Interaktuatu eguneratze- eta eskuratze-sistemekin"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Eskuratze-sistemarekin nahiz sistema-eguneratzeekin interaktuatzeko aukera ematen die aplikazioei."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Sortu multimedia-edukia proiektatzeko saioak"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Uneko erabiltzailea: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Jabea"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Errorea"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Zure administratzaileak ez du aldaketa egiteko baimena eman"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Ez da ekintza gauza dezakeen aplikaziorik aurkitu"</string>
     <string name="revoke" msgid="5404479185228271586">"Baliogabetu"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0 (Europa)"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN kodea"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"desblokeatzeko eredua"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"pasahitza"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 0ec1884..9eed755 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"‏به یک برنامه کاربردی اجازه ارائه مجوز و استفاده از گواهی‌های DRM را می‌دهد. هرگز برای برنامه‌های عادی مورد نیاز نیست."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"‏دریافت وضعیت انتقال پرتوی Android"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"‏به برنامه امکان می‌دهد تا اطلاعاتی درباره انتقال‌های کنونی پرتوی Android به دست آورد"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"تنظیم قوانین رمز ورود"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"‏طول و نویسه‎های مجاز در گذرواژه‌های بازکردن قفل صفحه را کنترل کنید."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"نمایش تلاش‌های قفل گشایی صفحه"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"قالب"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏اتصال رفع عیب USB"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"‏برای غیرفعال کردن اشکال زدایی USB لمس کنید."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"انتخاب روش ورودی"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"تنظیم روش‌های ورودی"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"صفحه‌کلید فیزیکی"</string>
     <string name="hardware" msgid="7517821086888990278">"سخت‌افزار"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"انتخاب طرح‌بندی صفحه‌کلید"</string>
@@ -1384,12 +1390,12 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"اجازه می‌دهد برنامه‌ای محافظ کلید را کنترل کند."</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"‏گوش دادن به تغییرات وضعیت trust."</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"‏به یک برنامه کاربردی برای گوش دادن به تغییرات در trust اجازه می‌دهد."</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"یک عامل مورد اعتماد فراهم می‌آورد."</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"به برنامه امکان می‌دهد یک عامل مورد اعتماد فراهم آورد."</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"راه‌اندازی منوی تنظیمات نماینده مورد اعتماد."</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"به یک برنامه اجازه می‌دهد تا فعالیتی را راه‌اندازی کند که رفتار نماینده مورد اعتماد را تغییر می‌دهد."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"‏اتصال به یک سرویس trust agent"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"‏به یک برنامه کاربردی برای اتصال به یک سرویس trust agent اجازه می‌دهد."</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"ارائه یک نماینده معتمد."</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"به یک برنامه اجازه می‌دهد یک نماینده معتمد ارائه دهد."</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"راه‌اندازی منوی تنظیمات نماینده معتمد."</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"به یک برنامه اجازه می‌دهد تا فعالیتی را راه‌اندازی کند که رفتار نماینده معتمد را تغییر می‌دهد."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"اتصال به یک سرویس نماینده معتمد"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"به یک برنامه کاربردی برای اتصال به یک سرویس نماینده معتمد اجازه می‌دهد."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"تعامل با سیستم به‌روزرسانی و بازیابی"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"به یک برنامه کاربردی اجازه می‌دهد با سیستم بازیابی و به‌روزرسانی‌های سیستم تعامل داشته باشد."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"ایجاد جلسات فرستادن رسانه"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"کاربر کنونی <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"دارنده"</string>
     <string name="error_message_title" msgid="4510373083082500195">"خطا"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"این تغییر از طرف سرپرستتان مجاز دانسته نشده است"</string>
     <string name="app_not_found" msgid="3429141853498927379">"برنامه‌ای برای انجام این عملکرد موجود نیست"</string>
     <string name="revoke" msgid="5404479185228271586">"لغو"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"پین"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"الگوی بازگشایی"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"گذرواژه"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index b24def8..4ccc2d6 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Antaa sovelluksen käyttää DRM-varmenteita ja hallita niiden käyttäjiä. Ei tavallisten sovellusten käyttöön."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Vastaanota Android Beam -siirron tilatietoja"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Antaa sovelluksen vastaanottaa tietoja nykyisistä Android Beam -siirroista"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Aseta salasanasäännöt"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Hallinnoi ruudun lukituksenpoistosalasanoissa sallittuja merkkejä ja salasanan pituutta."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Tarkkaile ruudun lukituksen poistoyrityksiä"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Muoto"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-vianetsintä yhdistetty"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Poista USB-vianetsintä käytöstä koskettamalla tätä."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Valitse syöttötapa"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Määritä syöttötavat"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fyysinen näppäimistö"</string>
     <string name="hardware" msgid="7517821086888990278">"Laitteisto"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Valitse näppäimistöasettelu"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Nykyinen käyttäjä: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Omistaja"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Virhe"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Järjestelmänvalvoja ei salli tätä muutosta"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Tätä toimintoa käsittelevää sovellusta ei löydy"</string>
     <string name="revoke" msgid="5404479185228271586">"Peruuta"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN-koodi"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"lukituksenpoistokuvio"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"salasana"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 7f1d754..c1d5375 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permet à une application de fournir et d\'utiliser les certificats de GDN. Cela ne devrait jamais être nécessaire pour les applications normales."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Recevoir des données sur l\'état du transfert Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Autoriser cette application à recevoir des données sur les transferts Android Beam en cours"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Définir les règles du mot de passe"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Choisir le nombre et le type de caractères autorisés dans les mots de passe de déverrouillage de l\'écran"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Gérer les tentatives de déverrouillage de l\'écran"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Mise en forme"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB connecté"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Appuyez pour désactiver le débogage USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Sélectionnez le mode de saisie"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Configurer les modes de saisie"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Clavier physique"</string>
     <string name="hardware" msgid="7517821086888990278">"Matériel"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Sélectionnez la disposition du clavier"</string>
@@ -1414,8 +1420,8 @@
     <string name="deny" msgid="2081879885755434506">"Refuser"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Autorisation demandée"</string>
     <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Autorisation demandée\npour le compte \"<xliff:g id="ACCOUNT">%s</xliff:g>\""</string>
-    <string name="forward_intent_to_owner" msgid="570916783072215572">"Vous utilisez cette application dans votre espace personnel."</string>
-    <string name="forward_intent_to_work" msgid="8624579696577525279">"Vous utilisez cette application dans votre espace de travail."</string>
+    <string name="forward_intent_to_owner" msgid="570916783072215572">"Vous utilisez cette application dans votre espace personnel"</string>
+    <string name="forward_intent_to_work" msgid="8624579696577525279">"Vous utilisez cette application dans votre espace de travail"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Mode de saisie"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Synchroniser"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibilité"</string>
@@ -1626,15 +1632,14 @@
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Supprimer"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Augmenter le volume au dessus du niveau recommandé ?\n\nL\'écoute prolongée à un volume élevé peut endommager vos facultés auditives."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Augmenter le volume au-dessus du niveau recommandé?\n\nL\'écoute prolongée à un volume élevé peut endommager vos facultés auditives."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Pour activer l\'accessibilité, appuyez de manière prolongée avec deux doigts."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"L\'accessibilité a bien été activée."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibilité annulée."</string>
     <string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="owner_name" msgid="2716755460376028154">"Propriétaire"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Erreur"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Cette modification n\'est pas autorisée par votre administrateur"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Aucune application trouvée pour gérer cette action."</string>
     <string name="revoke" msgid="5404479185228271586">"Révoquer"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"NIP"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"schéma de déverrouillage"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"mot de passe"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 09322a1..b5a301b 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permettre à une application de fournir et d\'utiliser des certificats de GDN. Ne devrait jamais être nécessaire pour les applications standards."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Recevoir des informations sur l\'état du transfert Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Autoriser cette application à recevoir des informations sur les transferts Android Beam en cours"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Définir les règles du mot de passe"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Choisir le nombre et le type de caractères autorisés dans les mots de passe de déverrouillage de l\'écran"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Gérer les tentatives de déverrouillage de l\'écran"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB activé"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Appuyez pour désactiver le débogage USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Sélectionnez le mode de saisie"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Configurer les modes de saisie"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Clavier physique"</string>
     <string name="hardware" msgid="7517821086888990278">"Matériel"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Sélectionnez la disposition du clavier"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="owner_name" msgid="2716755460376028154">"Propriétaire"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Erreur"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Votre administrateur n\'autorise pas cette modification."</string>
     <string name="app_not_found" msgid="3429141853498927379">"Aucune application trouvée pour gérer cette action."</string>
     <string name="revoke" msgid="5404479185228271586">"Révoquer"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"code PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"schéma de déverrouillage"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"mot de passe"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index a5e68f6..eb3ced4 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permite a unha aplicación fornecer e utilizar certificados DRM. Non se deberían precisar nunca para as aplicacións normais."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Recibir estado das transferencias de Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Permite a esta aplicación recibir información acerca das transferencias actuais de Android Beam"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Establecer as normas de contrasinal"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar a lonxitude e os caracteres permitidos nos contrasinais de desbloqueo da pantalla."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Supervisar os intentos de desbloqueo da pantalla"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formato"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB conectada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca para desactivar a depuración de erros de USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Escoller método de entrada"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Configurar métodos de entrada"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Teclado físico"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Seleccionar deseño de teclado"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Usuario actual <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Propietario"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Erro"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"O administrador non admite este cambio"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Non se atopou ningunha aplicación para procesar esta acción"</string>
     <string name="revoke" msgid="5404479185228271586">"Revogar"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"deseño de desbloqueo"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"contrasinal"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index df462d6..1ebf1a3 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -480,11 +480,11 @@
     <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"ऐप्स को स्‍टिकी प्रसारण भेजने देता है, जो प्रसारण समाप्त होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, टेबलेट की बहुत अधिक स्मृति का उपयोग करके उसे धीमा या अस्‍थिर कर सकता है."</string>
     <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"ऐप्स को स्‍टिकी प्रसारण भेजने देता है, जो प्रसारण समाप्त होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, फ़ोन की बहुत अधिक स्मृति का उपयोग करके उसे धीमा या अस्‍थिर कर सकता है."</string>
     <string name="permlab_readContacts" msgid="8348481131899886131">"अपने संपर्क पढ़ें"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"ऐप्स  को आपके टेबलेट में संग्रहीत संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से संवाद करने की आवृत्ति को पढ़ने देता है. यह अनुमति ऐप्स  को आपके संपर्क डेटा को सहेजने देती है, और दुर्भावनापूर्ण ऐप्स  आपकी जानकारी के बिना संपर्क डेटा को साझा कर सकते हैं."</string>
-    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"ऐप्स  को आपके फ़ोन में संग्रहीत संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से संवाद करने की आवृत्ति को पढ़ने देता है. यह अनुमति ऐप्स  को आपके संपर्क डेटा को सहेजने देती है, और दुर्भावनापूर्ण ऐप्स  आपकी जानकारी के बिना संपर्क डेटा को साझा कर सकते हैं."</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"ऐप्स  को आपके टेबलेट में संग्रहीत संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से डॉयलॉग करने की आवृत्ति को पढ़ने देता है. यह अनुमति ऐप्स  को आपके संपर्क डेटा को सहेजने देती है, और दुर्भावनापूर्ण ऐप्स  आपकी जानकारी के बिना संपर्क डेटा को साझा कर सकते हैं."</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"ऐप्स  को आपके फ़ोन में संग्रहीत संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से डॉयलॉग करने की आवृत्ति को पढ़ने देता है. यह अनुमति ऐप्स  को आपके संपर्क डेटा को सहेजने देती है, और दुर्भावनापूर्ण ऐप्स  आपकी जानकारी के बिना संपर्क डेटा को साझा कर सकते हैं."</string>
     <string name="permlab_writeContacts" msgid="5107492086416793544">"अपने संपर्क बदलें"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"ऐप्स  को आपके टेबलेट में संग्रहीत संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से संवाद करने की आवृत्ति को संशोधित करने देता है. यह अनुमति ऐप्स  को आपके संपर्क डेटा को हटाने देती है."</string>
-    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"ऐप्स  को आपके फ़ोन में संग्रहीत संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से संवाद करने की आवृत्ति को संशोधित करने देता है. यह अनुमति ऐप्स  को आपके संपर्क डेटा को हटाने देती है."</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"ऐप्स  को आपके टेबलेट में संग्रहीत संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से डॉयलॉग करने की आवृत्ति को संशोधित करने देता है. यह अनुमति ऐप्स  को आपके संपर्क डेटा को हटाने देती है."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"ऐप्स  को आपके फ़ोन में संग्रहीत संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से डॉयलॉग करने की आवृत्ति को संशोधित करने देता है. यह अनुमति ऐप्स  को आपके संपर्क डेटा को हटाने देती है."</string>
     <string name="permlab_readCallLog" msgid="3478133184624102739">"कॉल लॉग पढ़ें"</string>
     <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"ऐप्स  को आपके फ़ोन का कॉल लॉग पढ़ने देता है, जिसमें इनकमिंग और आउटगोइंग कॉल का डेटा शामिल है. यह अनुमति ऐप्स  को आपके कॉल लॉग डेटा को सहेजने देती है, और दुर्भावनापूर्ण ऐप्स  आपकी जानकारी के बिना कॉल लॉग डेटा को साझा कर सकते हैं."</string>
     <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"ऐप्स  को आपके फ़ोन का कॉल लॉग पढ़ने देता है, जिसमें इनकमिंग और आउटगोइंग कॉल का डेटा शामिल है. यह अनुमति ऐप्स  को आपके कॉल लॉग डेटा को सहेजने देती है, और दुर्भावनापूर्ण ऐप्स  आपकी जानकारी के बिना कॉल लॉग डेटा को साझा कर सकते हैं."</string>
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"ऐप्लिकेशन को DRM प्रमाणपत्रों का प्रावधान और उपयोग करने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यकता नहीं होना चाहिए."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android Beam स्थानान्तरण स्थिति प्राप्त करें"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"इस ऐप्लिकेशन को वर्तमान Android Beam स्थानान्तरणों के बारे में जानकारी प्राप्त करने देती है."</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियम सेट करें"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"स्‍क्रीन-अनलॉक पासवर्ड में अनुमति प्राप्त लंबाई और वर्णों को नियंत्रित करें."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"स्‍क्रीन-अनलॉक के प्रयासों पर निगरानी रखें"</string>
@@ -1048,8 +1052,8 @@
     <string name="searchview_description_submit" msgid="2688450133297983542">"क्वेरी सबमिट करें"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"बोलकर खोजें"</string>
     <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"स्‍पर्श के द्वारा अन्‍वेषण करें सक्षम करें?"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्‍पर्श के द्वारा अन्‍वेषण करें सक्षम करना चाहती है. स्‍पर्श के द्वारा अन्‍वेष करें चालू होने पर, आप अपनी अंगुली के नीचे क्या है उसका विवरण सुन सकते हैं या देख सकते हैं या टेबलेट से संवाद करने के लिए जेस्‍चर निष्‍पादित कर सकते हैं."</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्‍पर्श के द्वारा अन्‍वेषण करें सक्षम करना चाहती है. स्‍पर्श के द्वारा अन्‍वेष करें चालू होने पर, आप अपनी अंगुली के नीचे क्या है उसका विवरण सुन सकते हैं या देख सकते हैं या फ़ोन से संवाद करने के लिए जेस्‍चर निष्‍पादित कर सकते हैं."</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्‍पर्श के द्वारा अन्‍वेषण करें सक्षम करना चाहती है. स्‍पर्श के द्वारा अन्‍वेष करें चालू होने पर, आप अपनी अंगुली के नीचे क्या है उसका विवरण सुन सकते हैं या देख सकते हैं या टेबलेट से डॉयलॉग करने के लिए जेस्‍चर निष्‍पादित कर सकते हैं."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्‍पर्श के द्वारा अन्‍वेषण करें सक्षम करना चाहती है. स्‍पर्श के द्वारा अन्‍वेष करें चालू होने पर, आप अपनी अंगुली के नीचे क्या है उसका विवरण सुन सकते हैं या देख सकते हैं या फ़ोन से डॉयलॉग करने के लिए जेस्‍चर निष्‍पादित कर सकते हैं."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 माह पहले"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 माह से पहले"</string>
   <plurals name="num_seconds_ago">
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"प्रारूपित करें"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग करना कनेक्ट किया गया"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB डीबग करना अक्षम करने के लिए स्‍पर्श करें."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"इनपुट पद्धति चुनें"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"इनपुट पद्धतियां सेट करें"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"भौतिक कीबोर्ड"</string>
     <string name="hardware" msgid="7517821086888990278">"हार्डवेयर"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"कीबोर्ड लेआउट को चुनें"</string>
@@ -1386,10 +1392,10 @@
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"किसी ऐप्लिकेशन को ट्रस्ट स्थिति के बदलावों को सुनने की अनुमति देती है."</string>
     <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"विश्वसनीय एजेंट प्रदान करें."</string>
     <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"ऐप्लिकेशन को विश्वसनीय एजेंट प्रदान करने देती है."</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"विश्वस्त एजेंट सेटिंग मेनू लॉन्च करें."</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"ऐप्लिकेशन को ऐसी गतिविधि लॉन्च करने देती है जो विश्वस्त एजेंट के व्यवहार में बदलाव लाती है."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"ट्रस्ट एजेंट सेवा से आबद्ध करना"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"किसी ऐप्लिकेशन को ट्रस्ट एजेंट सेवा से आबद्ध करने की अनुमति देती है."</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"विश्वसनीय एजेंट सेटिंग मेनू लॉन्च करें."</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"ऐप्लिकेशन को ऐसी गतिविधि लॉन्च करने देती है जो विश्वसनीय एजेंट के व्यवहार में बदलाव लाती है."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"विश्वसनीय एजेंट सेवा से जुड़ें"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"किसी ऐप्लिकेशन को विश्वसनीय एजेंट सेवा से जुडॉव की अनुमति देती है."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"अपडेट और पुनर्प्राप्ति सिस्टम के साथ सहभागिता करें"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"ऐप्लिकेशन को पुनर्प्राप्ति सिस्टम और सिस्टम अपडेट के साथ सहभागिता करने देती है."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"मीडिया प्रोजेक्शन सत्र बनाएं"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"वर्तमान उपयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"स्वामी"</string>
     <string name="error_message_title" msgid="4510373083082500195">"त्रुटि"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"यह बदलाव आपके व्यवस्थापक द्वारा अनुमत नहीं है"</string>
     <string name="app_not_found" msgid="3429141853498927379">"इस कार्यवाही को प्रबंधित करने के लिए कोई ऐप्स  नहीं मिला"</string>
     <string name="revoke" msgid="5404479185228271586">"निरस्‍त करें"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"पिन"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"पैटर्न अनलॉक करें"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"पासवर्ड"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 425de47..3737f68 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Aplikaciji omogućuje pružanje i korištenje DRM certifikata. Ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Primanje statusa prijenosa Android Beama"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Omogućuje aplikaciji primanje podataka o trenutačnim prijenosima Android Beama"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Postavi pravila zaporke"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Upravljajte duljinom zaporki za otključavanje zaslona i dopuštenim znakovima u tim zaporkama."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Nadgledaj pokušaje otključavanja zaslona"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Priključen je alat za uklanjanje programske pogreške USB-a"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Dodirnite da biste onemogućili rješavanje programske pogreške na USB-u."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Odabir načina unosa"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Postavljanje načina unosa"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fizička tipkovnica"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardver"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Odaberite izgled tipkovnice"</string>
@@ -1388,8 +1394,8 @@
     <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Omogućuje aplikaciji pružanje agenta za pouzdanost."</string>
     <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Pokrenite izbornik postavki agenta za pouzdanost."</string>
     <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Aplikaciji dopušta pokretanje aktivnosti koja mijenja ponašanje agenta za pouzdanost."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Povezivanje s uslugom pouzdanog predstavnika"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Omogućuje aplikaciji povezivanje s uslugom pouzdanog predstavnika."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Povezivanje s uslugom agenta za pouzdanost"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Omogućuje aplikaciji povezivanje s uslugom agenta za pouzdanost."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Interakcija s ažuriranjem i sustavom za oporavak"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Omogućuje aplikaciji interakciju sa sustavom za oporavak i ažuriranjima sustava."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Stvaranje sesija za projiciranje medija"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Trenutačni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Vlasnik"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Pogreška"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Vaš administrator ne dopušta tu promjenu"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nije pronađena aplikacija za upravljanje ovom radnjom"</string>
     <string name="revoke" msgid="5404479185228271586">"Opozovi"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"uzorak za otključavanje"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"zaporka"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 441d6dc..c43a2a8 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Engedélyezi egy alkalmazás számára a DRM-tanúsítványokhoz való hozzáférést és azok használatát. Átlagos alkalmazásoknak erre nem lehet szükségük."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android Beam-átviteli állapot fogadása"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Lehetővé teszi az alkalmazás számára a folyamatban lévő Android Beam-átvitelekről szóló információk fogadását"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Jelszavakkal kapcsolatos szabályok beállítása"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"A képernyőzár-feloldási jelszavakban engedélyezett karakterek és hosszúság vezérlése."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Képernyőzár-feloldási kísérletek figyelése"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formázás"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hibakereső csatlakoztatva"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Érintse meg az USB hibakeresés kikapcsolásához."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Beviteli mód kiválasztása"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Beviteli módok beállítása"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fizikai billentyűzet"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardver"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Válasszon billentyűzetkiosztást"</string>
@@ -1384,10 +1390,10 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Lehetővé teszi egy alkalmazás számára a billentyűzár vezérlését."</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"Trust-állapot változásának figyelése"</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"Lehetővé teszi, hogy az alkalmazás figyelje a trust-állapot változásait."</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Trust agent szoftver megadása"</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Lehetővé teszi, hogy az alkalmazás megadjon egy trust agent szoftvert."</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"A trust agent beállításait tartalmazó menü indítása."</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Lehetővé teszi, hogy egy alkalmazás olyan tevékenységet indítson el, amely megváltoztatja a trust agent viselkedését."</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Trust agent komponens megadása"</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Lehetővé teszi, hogy az alkalmazás megadjon egy trust agent komponenst."</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"A trust agent komponens beállításait tartalmazó menü indítása."</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Lehetővé teszi, hogy egy alkalmazás olyan tevékenységet indítson el, amely megváltoztatja a trust agent komponens viselkedését."</string>
     <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Csatlakozás egy trust agent szolgáltatáshoz"</string>
     <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Lehetővé teszi, hogy az alkalmazás egy trust agent szolgáltatáshoz csatlakozzon."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Kapcsolatfelvétel a frissítési és helyreállítási rendszerrel"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> az aktuális felhasználó."</string>
     <string name="owner_name" msgid="2716755460376028154">"Tulajdonos"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Hiba"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Rendszergazdája nem engedélyezi ezt a módosítást"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nincs megfelelő alkalmazás a művelet elvégzésére."</string>
     <string name="revoke" msgid="5404479185228271586">"Visszavonás"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"„ISO A0” méret"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN kód"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"feloldási minta"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"jelszó"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index d72dd18..51e6c3a 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Ծրագրին թույլ է տալիս տրամադրել և օգտագործել DRM վկայագրեր: Սովորական ծրագրերի համար երբեք պետք չի գալիս:"</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Ստանալ Android Beam-ով փոխանցման կարգավիճակը"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Ծրագրին թույլ է տալիս ստանալ Android Beam-ով ընթացիկ փոխանցումների մասին տեղեկատվություն:"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Սահմանել գաղտնաբառի կանոնները"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Վերահսկել էկրանի ապակողպման գաղտնաբառերի թույլատրելի երկարությունն ու գրանշանները:"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Վերահսկել էկրանի ապակողպման փորձերը"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Ձևաչափ"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB վրիպազերծումը միացված է"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Հպեք` USB կարգաբերումը կասեցնելու համար:"</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Ընտրեք մուտքագրման եղանակը"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Կարգավորել ներածման եղանակները"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Ֆիզիկական ստեղնաշար"</string>
     <string name="hardware" msgid="7517821086888990278">"Սարքաշար"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Ընտրեք ստեղնաշարի դիրքը"</string>
@@ -1384,12 +1390,12 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Թույլ է տալիս հավելվածին կառավարել ստեղնաշարի պաշտպանիչը:"</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"Լսել վստահության կարգավիճակի ​փոփոխությունները:"</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"Ծրագրին թույլ է տալիս լսել վստահության կարգավիճակի փոփոխությունները:"</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Տրամադրել վստահելի գործակալ:"</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Ծրագրին թույլ է տալիս տրամադրել վստահելի գործակալ:"</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Գործարկել վստահելի գործակալի կարգավորումների ընտրացանկը:"</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Թույլ է տալիս ծրագրին գործարկել մի գործողություն, որը փոխում է վստահելի գործակալի վարքագիծը:"</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Կապվել վստահելի գործակալի ծառայությանը"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Ծրագրին թույլ է տալիս կապվել վստահելի գործակալի ծառայությանը:"</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Միջանկյալ գործակալի տրամադրում:"</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Հավելվածը կարող է միջանկյալ գործակալ տրամադրել:"</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Միջանկյալ գործակալի կարգավորումների ընտրացանկի գործարկում"</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Հավելվածը կարող է գործարկել գործողություն, որը փոխում է միջանկյալ գործակալի վարքագիծը:"</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Կապակցում միջանկյալ գործակալի ծառայությանը"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Հավելվածը կարող է կապակցվել միջանկյալ գործակալի ծառայությանը:"</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Փոխազդել թարմացման և վերականգնման համակարգի հետ"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Թույլ է տալիս ծրագրին փոխազդել վերականգնման համակարգի և համակարգի թարմացումների հետ:"</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Ստեղծել մեդիայի տեսարձակման աշխատաշրջաններ"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Ներկայիս օգտվողը <xliff:g id="NAME">%1$s</xliff:g>:"</string>
     <string name="owner_name" msgid="2716755460376028154">"Սեփականատեր"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Սխալ"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Այս փոփոխությունը չի թույլատրվում ձեր ադմինիստրատորի կողմից:"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Այս գործողությունը կատարելու համար ոչ մի ծրագիր չի գտնվել:"</string>
     <string name="revoke" msgid="5404479185228271586">"Չեղարկել"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"ապակողպող նախշ"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"գաղտնաբառ"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 50e96de..adfdd44 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Memungkinkan aplikasi menyediakan dan menggunakan sertifikat DRM. Tidak pernah dibutuhkan untuk aplikasi normal."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Menerima status transfer Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Memungkinkan aplikasi ini menerima informasi tentang transfer Android Beam saat ini"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Setel aturan sandi"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrol panjang dan karakter yang diizinkan dalam sandi pembuka layar."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Upaya pembukaan kunci layar monitor"</string>
@@ -812,7 +816,7 @@
     <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Faks Rumah"</string>
     <string name="phoneTypePager" msgid="7582359955394921732">"Pager"</string>
     <string name="phoneTypeOther" msgid="1544425847868765990">"Lainnya"</string>
-    <string name="phoneTypeCallback" msgid="2712175203065678206">"Panggil balik"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"Telepon balik"</string>
     <string name="phoneTypeCar" msgid="8738360689616716982">"Mobil"</string>
     <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Utama Perusahaan"</string>
     <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Debugging USB terhubung"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Sentuh untuk menonaktifkan debugging USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Pilih metode masukan"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Menyiapkan metode masukan"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Keyboard fisik"</string>
     <string name="hardware" msgid="7517821086888990278">"Perangkat Keras"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Pilih tata letak keyboard"</string>
@@ -1388,8 +1394,8 @@
     <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Memungkinkan aplikasi memberikan agen tepercaya."</string>
     <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Luncurkan menu setelan agen tepercaya."</string>
     <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Izinkan aplikasi meluncurkan aktivitas yang mengubah perilaku agen tepercaya."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Ikat ke layanan agen kepercayaan"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Mengizinkan aplikasi mengikat ke layanan agen kepercayaan."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Ikat ke layanan agen tepercaya"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Mengizinkan aplikasi mengikat ke layanan agen tepercaya."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Berinteraksi dengan sistem pemulihan dan pembaruan"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Mengizinkan aplikasi berinteraksi dengan sistem pemulihan dan pembaruan sistem."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Membuat sesi proyeksi media"</string>
@@ -1405,7 +1411,7 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Selesai"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Sebelumnya"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Lakukan"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Panggil nomor \nmenggunakan<xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Telepon nomor \nmenggunakan<xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="create_contact_using" msgid="4947405226788104538">"Buat kontak \nmenggunakan <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Satu atau beberapa apl meminta izin untuk mengakses akun Anda, sekarang dan di masa mendatang."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Apakah Anda ingin mengizinkan permintaan ini?"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Pengguna saat ini <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Pemilik"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Kesalahan"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Perubahan ini tidak diizinkan oleh administrator Anda"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Tidak ada aplikasi yang ditemukan untuk menangani tindakan ini"</string>
     <string name="revoke" msgid="5404479185228271586">"Cabut"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"pola pembuka kunci"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"sandi"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index f77ae33..d3b86ad 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Leyfir forriti að úthluta og nota DRM-vottorð. Ætti aldrei að þurfa fyrir venjuleg forrit."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Fá flutningsstöðu Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Leyfir þessu forriti að fá upplýsingar um flutning sem fram fer með Android Beam"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Setja reglur um aðgangsorð"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Stjórna lengd aðgangsorða til að taka skjáinn úr lás og leyfðum stöfum."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Fylgjast með tilraunum til að taka skjáinn úr lás"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Forsníða"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-villuleit tengd"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Snertu til að slökkva á USB-villuleit."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Veldu innsláttaraðferð"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Setja upp innsláttaraðferðir"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Vélbúnaðarlyklaborð"</string>
     <string name="hardware" msgid="7517821086888990278">"Vélbúnaður"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Veldu lyklaskipan"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Núverandi notandi <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Eigandi"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Villa"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Stjórnandinn þinn leyfir ekki þessa breytingu."</string>
     <string name="app_not_found" msgid="3429141853498927379">"Ekkert forrit fannst til að meðhöndla þessa aðgerð"</string>
     <string name="revoke" msgid="5404479185228271586">"Afturkalla"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN-númer"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"opnunarmynstur"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"aðgangsorð"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index b04ac30..5e4efa2 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Consente a un\'app di fornire e utilizzare ceritificati DRM. Questa opzione non deve essere utilizzata per app normali."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Ricevi lo stato dei trasferimenti Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Consente all\'applicazione di ricevere informazioni sugli attuali trasferimenti Android Beam"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Impostazione regole password"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlla la lunghezza e i caratteri ammessi nelle password di sblocco dello schermo."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Controllo tentativi di sblocco dello schermo"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatta"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Debug USB collegato"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Tocca per disattivare il debug USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Scegli il metodo di immissione"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Configura metodi di immissione"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Tastiera fisica"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Seleziona layout tastiera"</string>
@@ -1384,12 +1390,12 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Consente a un\'applicazione di controllare keguard."</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"Rilevamento modifiche dello stato trust."</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"Consente a un\'applicazione di rilevare le modifiche nello stato trust."</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Indica un trust agent."</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Consente a un\'applicazione di indicare un trust agent."</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Avvio del menu di impostazioni del trust agent."</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Consente a un\'applicazione di avviare un\'attività che modifica il comportamento di un trust agent."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Associazione a un servizio trust agent"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Consente a un\'applicazione di associarsi a un servizio trust agent."</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Indica un agente di attendibilità."</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Consente a un\'applicazione di indicare un agente di attendibilità."</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Avvio del menu di impostazioni dell\'agente di attendibilità."</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Consente a un\'applicazione di avviare un\'attività che modifica il comportamento di un agente di attendibilità."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Associazione a un agente di attendibilità"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Consente a un\'applicazione di associarsi a un agente di attendibilità."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Interazione con il sistema di ripristino e aggiornamento"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Consente a un\'applicazione di interagire con il sistema di ripristino e con gli aggiornamenti di sistema."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Crea sessioni di proiezioni multimediali"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Utente corrente <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Proprietario"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Errore"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Questa modifica non è consentita dal tuo amministratore"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nessuna applicazione trovata in grado di gestire questa azione"</string>
     <string name="revoke" msgid="5404479185228271586">"Revoca"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"sequenza di sblocco"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"password"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 8afdb86..057c105 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"‏מאפשרת לאפליקציה לנהל תצורה של אישורי DRM ולהשתמש בהם. לעולם לא אמורה להיות נחוצה עבור אפליקציה רגילה."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"‏קבלת סטטוס העברה של Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"‏מאפשר לאפליקציה הזו לקבל מידע על העברות Android Beam נוכחיות"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"הגדר כללי סיסמה"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"שלוט באורך ובתווים המותרים בסיסמאות לביטול נעילת מסך."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"עקוב אחר ניסיונות לביטול נעילת מסך"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"פרמוט"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏ניקוי באגים של USB מחובר"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"‏גע כדי להשבית את ניקוי הבאגים בהתקן ה-USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"בחר שיטת הזנה"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"הגדר שיטות קלט"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"מקלדת פיזית"</string>
     <string name="hardware" msgid="7517821086888990278">"חומרה"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"בחירת פריסת מקלדת"</string>
@@ -1384,12 +1390,12 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"מאפשר לאפליקציה לשלוט במגן המקלדת."</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"חיפוש שינויים במצב אמון."</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"מאפשר לאפליקציה לחפש שינויים במצב אמון."</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"ציון סוכן אמון."</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"מאפשר לאפליקציה לספק סוכן אמון."</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"הפעלה של תפריט ההגדרות עבור סוכן האמון."</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"מאפשר לאפליקציה להפעיל פעילות המשנה את התנהגות סוכן האמון."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"איגוד אל שירות סוכן אמון"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"מאפשר לאפליקציה לאגוד אל שירות סוכן אמון."</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"ציון סביבה אמינה."</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"מאפשר לאפליקציה לספק סביבה אמינה."</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"הפעלה של תפריט ההגדרות עבור סביבה אמינה."</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"מאפשר לאפליקציה להפעיל פעילות המשנה את התנהגות הסביבה האמינה."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"איגוד אל שירות סביבה אמינה"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"מאפשר לאפליקציה לאגוד אל שירות סביבה אמינה."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"אינטראקציה עם מערכת שחזור ועדכונים"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"מאפשרת לאפליקציה ליצור אינטראקציה עם מערכת השחזור ועדכוני מערכת."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"יצירת פעילות של הקרנת מדיה"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"המשתמש הנוכחי <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"בעלים"</string>
     <string name="error_message_title" msgid="4510373083082500195">"שגיאה"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"מנהל המערכת שלך אינו מתיר שינוי זה"</string>
     <string name="app_not_found" msgid="3429141853498927379">"לא נמצאה אפליקציה שתומכת בפעולה זו"</string>
     <string name="revoke" msgid="5404479185228271586">"בטל"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"‏מספר PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"קו ביטול נעילה"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"סיסמה"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 1d99f3d..ac76478 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"DRM証明書のプロビジョニングと使用をアプリに許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Androidビーム転送のステータスを受信"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"現在のAndroidビーム転送に関する情報を受信することをこのアプリに許可します。"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"パスワードルールの設定"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"画面ロック解除パスワードの長さと使用できる文字を制御します。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"画面ロック解除試行の監視"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"フォーマット"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"タップしてUSBデバッグを無効にします。"</string>
-    <string name="select_input_method" msgid="4653387336791222978">"入力方法の選択"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"入力方法をセットアップ"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"物理キーボード"</string>
     <string name="hardware" msgid="7517821086888990278">"ハードウェア"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"キーボードレイアウトの選択"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"現在のユーザーは<xliff:g id="NAME">%1$s</xliff:g>です。"</string>
     <string name="owner_name" msgid="2716755460376028154">"所有者"</string>
     <string name="error_message_title" msgid="4510373083082500195">"エラー"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"この変更は管理者によって許可されていません"</string>
     <string name="app_not_found" msgid="3429141853498927379">"この操作を行うアプリが見つかりません"</string>
     <string name="revoke" msgid="5404479185228271586">"取り消し"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"ロック解除パターン"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"パスワード"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 05ac254..454ed0d 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"საშუალებას აძლევს აპლიკაციას დანერგოს და გამოიყენოს DRM სერთიფიკატები. ეს უფლება ჩვეულებრივ აპებს არ ჭირდება."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android Beam ტრანსფერის სტატუსის მიღება"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"ნებას რთავს ამ აპლიკაციას, მიიღოს ინფორმაცია მიმდინარე Android Beam-ის ტრანსფერების შესახებ"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"პაროლის წესების დაყენება"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"გააკონტროლეთ ეკრანის განბლოკვის პაროლში დაშვებული სიმბოლოები და მისი სიგრძე."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ეკრანის განბლოკვის მცდელობების გაკონტროლება"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"დაფორმატება"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB გამართვა შეერთებულია"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"შეეხეთ, რათა შეწყვიტოთ USB-ის გამართვა."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"აირჩიეთ შეყვანის მეთოდი"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"შეყვანის მეთოდების დაყენება"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"ფიზიკური კლავიატურა"</string>
     <string name="hardware" msgid="7517821086888990278">"მოწყობილობა"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"შეარჩიეთ კლავიატურის განლაგება."</string>
@@ -1384,12 +1390,12 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"აპლიკაციას შეეძლება ღილაკების დამცავის კონტროლი."</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"ნდობის მდგომარეობის ცვლილებების მოსმენა."</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"საშუალებას აძლევს აპლიკაციას მოუსმინოს ცვლილებებს სანდო მდგომარეობაში."</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"სანდო აგენტის წარმოდგენა."</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"საშუალებას აძლევს აპლიკაციას წარმოადგინოს სანდო აგენტი."</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"ნდობის აგენტის წარმოდგენა."</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"საშუალებას აძლევს აპლიკაციას წარმოადგინოს ნდობის აგენტი."</string>
     <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"ნდობის აგენტის პარამეტრების მენიუს გამოძახება."</string>
     <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"აძლევს აპლიკაციას ნებართვას წამოიწყოს აქტივობა, რომელიც ნდობის აგენტის ქცევას ცვლის."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"სანდო აგენტის სერვისზე მიმაგრება."</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"საშუალებას აძლევს აპლიკაციას მიემაგროს სანდო აგენტის სერვისს."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"ნდობის აგენტის სერვისზე მიმაგრება."</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"საშუალებას აძლევს აპლიკაციას მიემაგროს ნდობის აგენტის სერვისს."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"განახლებასთან და აღდგენის სისტემასთან ინტერაქცია"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"საშუალებას აძლევს აპლიკაციას მოახდინოს აღდგენის სისტემასთან და სისტემის განახლებასთან ინტერაქცია."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"მედია პროეცირების სესიების შექმნა"</string>
@@ -1414,8 +1420,8 @@
     <string name="deny" msgid="2081879885755434506">"აკრძალვა"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"მოთხოვნილია ნებართვა"</string>
     <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"მოთხოვნილია ნებრათვა \nანგარიშისთვის: <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
-    <string name="forward_intent_to_owner" msgid="570916783072215572">"ამ აპს თვენს პერსონალურ სივრცეში იყენებთ"</string>
-    <string name="forward_intent_to_work" msgid="8624579696577525279">"ამ აპს თვენს სამუშაო სივრცეში იყენებთ"</string>
+    <string name="forward_intent_to_owner" msgid="570916783072215572">"ამ აპს თქვენს პერსონალურ სივრცეში იყენებთ"</string>
+    <string name="forward_intent_to_work" msgid="8624579696577525279">"ამ აპს თქვენს სამუშაო სივრცეში იყენებთ"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"შეყვანის მეთოდი"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"სინქრონიზაცია"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"წვდომა"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"ამჟამინდელი მომხმარებელი <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"მფლობელი"</string>
     <string name="error_message_title" msgid="4510373083082500195">"შეცდომა"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"ეს ცვლილება თქვენი დომენის ადმინისტრატორის მიერ ნებადართული არ არის."</string>
     <string name="app_not_found" msgid="3429141853498927379">"ამ მოქმედების შესასრულებლად აპლიკაცია ვერ მოიძებნა"</string>
     <string name="revoke" msgid="5404479185228271586">"გაუქმება"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN-კოდი"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"განბლოკვის ნიმუში"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"პაროლი"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 480a481..cd5c34c 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Қолданбаға DRM сертификаттарын қамтамасыз етуге және пайдалануға рұқсат береді. Қалыпты қолданбалар үшін ешқашан қажет болмайды."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android Beam тасымалдау күйін алу"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Осы қолданбаға ағымдағы Android Beam тасымалдаулары туралы ақпарат алуға рұқсат ету"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Кілтсөз ережелерін тағайындау"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Экранды ашу кілтсөздерінің ұзындығы мен қолдануға болатын таңбаларды басқару."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Экранды ашу әркеттерін бақылау"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Формат"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB жөндеу қосылған"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB күйін келтіруді өшіру үшін түртіңіз."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Енгізу әдісін таңдау"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Енгізу әдістерін реттеу"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Қатты пернетақта"</string>
     <string name="hardware" msgid="7517821086888990278">"Компьютерлік жабдық"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Пернетақта орналасуын таңдау"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Ағымдағы пайдаланушы <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Пайдаланушы"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Қателік"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Бұл өзгертуге әкімші рұқсат етпеген"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Бұл әрекетті орындайтын қолданба табылмады"</string>
     <string name="revoke" msgid="5404479185228271586">"Бас тарту"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"бекітпесін ашу әдісі"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"құпия сөз"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index ce3214c..9383134 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"ឲ្យ​កម្មវិធី​ផ្ដល់ និង​ប្រើ​វិញ្ញាបនបត្រ DRM ។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"ទទួល​ស្ថានភាព​ផ្ទេរ Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"ឲ្យ​កម្មវិធី​ទទួល​ព័ត៌មាន​អំពី​ការ​ផ្ទេរ​​ Android Beam បច្ចុប្បន្ន"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"កំណត់​ក្បួន​ពាក្យ​សម្ងាត់"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"ពិនិត្យ​ប្រវែង និង​តួអក្សរ​ដែល​បាន​អនុញ្ញាត​ក្នុង​ពាក្យ​សម្ងាត់​ចាក់​សោ​អេក្រង់។"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ពិនិត្យ​ការ​ព្យាយាម​ដោះ​សោ​អេក្រង់"</string>
@@ -1341,8 +1345,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"ធ្វើ​ទ្រង់ទ្រាយ"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"បាន​ភ្ជាប់​ការ​កែ​កំហុស​យូអេសប៊ី"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"ប៉ះ ដើម្បី​បិទ​ការ​កែ​កំហុស​យូអេសប៊ី។"</string>
-    <string name="select_input_method" msgid="4653387336791222978">"ជ្រើស​វិធីសាស្ត្រ​បញ្ចូល"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"រៀបចំ​វិធីសាស្ត្រ​បញ្ចូល"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"ក្ដារ​ចុច​​ពិតប្រាកដ"</string>
     <string name="hardware" msgid="7517821086888990278">"ផ្នែក​រឹង"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"ជ្រើស​ប្លង់​ក្ដារ​ចុច"</string>
@@ -1635,8 +1641,7 @@
     <string name="user_switched" msgid="3768006783166984410">"អ្នក​ប្រើ​បច្ចុប្បន្ន <xliff:g id="NAME">%1$s</xliff:g> ។"</string>
     <string name="owner_name" msgid="2716755460376028154">"ម្ចាស់"</string>
     <string name="error_message_title" msgid="4510373083082500195">"កំហុស"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"ការ​ផ្លាស់ប្ដូរ​នេះ​មិន​ត្រូវ​បាន​អនុញ្ញាត​ដោយ​អ្នក​គ្រប់គ្រង​របស់​អ្នក​ទេ"</string>
     <string name="app_not_found" msgid="3429141853498927379">"រក​មិន​ឃើញ​កម្មវិធី​ ដើម្បី​គ្រប់គ្រង​សកម្មភាព​នេះ"</string>
     <string name="revoke" msgid="5404479185228271586">"ដកហូត"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1767,4 +1772,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"កូដ PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"លំនាំ​ដោះ​សោ"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"ពាក្យ​សម្ងាត់"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index a657235..b24de8b 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"DRM ಪ್ರಮಾಣಪತ್ರಗಳಿಗೆ ಅನುಮತಿ ಕಲ್ಪಿಸಲು ಮತ್ತು ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android Beam ವರ್ಗಾವಣೆ ಸ್ಥಿತಿಯನ್ನು ಸ್ವೀಕರಿಸಿ"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"ಪ್ರಸ್ತುತ Android Beam ವರ್ಗಾವಣೆಗಳ ಕುರಿತ ಮಾಹಿತಿಯನ್ನು ಸ್ವೀಕರಿಸಲು ಈ ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸಿ"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"ಪಾಸ್‌ವರ್ಡ್ ನಿಮಯಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"ಪರದೆ-ಅನ್‍‍ಲಾಕ್ ಪಾಸ್‍‍ವರ್ಡ್‌ಗಳಲ್ಲಿ ಅನುಮತಿಸಿರುವ ಅಳತೆ ಮತ್ತು ಅಕ್ಷರಗಳನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ಪರದೆಯ-ಅನ್‌ಲಾಕ್ ಪ್ರಯತ್ನಗಳನ್ನು ಮಾನಿಟರ್ ಮಾಡಿ"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"ಸ್ವರೂಪಿಸು"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಸ್ಪರ್ಶಿಸಿ."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"ಇನ್‌ಪುಟ್‌‌ ವಿಧಾನವನ್ನು ಆರಿಸಿ"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"ಇನ್‌ಪುಟ್ ವಿಧಾನಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್"</string>
     <string name="hardware" msgid="7517821086888990278">"ಹಾರ್ಡ್‌ವೇರ್"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"ಕೀಬೋರ್ಡ್ ಲೇಔಟ್ ಆಯ್ಕೆಮಾಡಿ"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"ಪ್ರಸ್ತುತ ಬಳಕೆದಾರರು <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"ಮಾಲೀಕರು"</string>
     <string name="error_message_title" msgid="4510373083082500195">"ದೋಷ"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"ಈ ಬದಲಾವಣೆಯನ್ನು ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
     <string name="app_not_found" msgid="3429141853498927379">"ಈ ಕ್ರಿಯೆಯನ್ನು ನಿರ್ವಹಿಸಲು ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್ ಕಂಡುಬಂದಿಲ್ಲ"</string>
     <string name="revoke" msgid="5404479185228271586">"ಹಿಂತೆಗೆದುಕೊಳ್ಳಿ"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"ಅನ್‌ಲಾಕ್ ನಮೂನೆ"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"ಪಾಸ್‌ವರ್ಡ್"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 17cc6cf..52f9afc 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"애플리케이션이 DRM 인증서를 프로비저닝하고 사용하도록 허용합니다. 일반 앱에서는 필요하지 않습니다."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android Beam 전송 상태 수신"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"이 애플리케이션이 현재 Android Beam 전송 관련 정보를 수신하도록 허용합니다."</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"비밀번호 규칙 설정"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"화면 잠금해제 비밀번호에 허용되는 길이 및 문자 수를 제어합니다."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"화면 잠금해제 시도 모니터링"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"포맷"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB 디버깅 연결됨"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB 디버깅을 사용하지 않으려면 터치하세요."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"입력 방법 선택"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"입력 방법 설정"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"물리적 키보드"</string>
     <string name="hardware" msgid="7517821086888990278">"하드웨어"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"키보드 레이아웃 선택"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"현재 사용자는 <xliff:g id="NAME">%1$s</xliff:g>님입니다."</string>
     <string name="owner_name" msgid="2716755460376028154">"소유자"</string>
     <string name="error_message_title" msgid="4510373083082500195">"오류"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"관리자가 이 변경을 허용하지 않습니다."</string>
     <string name="app_not_found" msgid="3429141853498927379">"이 작업을 처리하는 애플리케이션을 찾을 수 없습니다."</string>
     <string name="revoke" msgid="5404479185228271586">"취소"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"잠금해제 패턴"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"비밀번호"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index bd574e5..fa4411e 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -953,6 +953,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Колдонмого DRM тастыктамаларын ишке киргизип, колдонуу мүмкүнчүлүгүн берет. Кадимки колдонмолорго эч качан талап кылынбайт."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android Beam өткөрүү абалын алуу"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Бул колдонмого учурдагы Android Beam өткөрүүлөрү жөнүндө маалымат алуу мүмкүнчүлүгүн берет"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <!-- no translation found for policylab_limitPassword (4497420728857585791) -->
     <skip />
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Экранды бөгөттөн чыгаруу сырсөзүнүн узундугун жана уруксат берилген белгилерди башкаруу."</string>
@@ -1735,8 +1739,10 @@
     <!-- no translation found for adb_active_notification_title (6729044778949189918) -->
     <skip />
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB мүчүлүштүктөрдү жоюу мүмкүнчүлүгүн өчүрүү үчүн тийип коюңуз."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Дайын киргизүү ыкмасын тандаңыз"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Киргизүү ыкмаларын орнотуу"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Аппараттык тергич"</string>
     <string name="hardware" msgid="7517821086888990278">"Аппараттык"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Тергичтин жайгашуусун тандоо"</string>
@@ -2115,8 +2121,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Учурдагы колдонуучу <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Ээси"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Ката"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Мындай өзгөртүүгө администраторуңуз тарабынан тыюу салынган."</string>
     <string name="app_not_found" msgid="3429141853498927379">"Бул аракетти аткаруучу эч бир колдонмо табылбады"</string>
     <string name="revoke" msgid="5404479185228271586">"Жокко чыгаруу"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0 (841mm x 1189mm)"</string>
@@ -2247,4 +2252,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"бөгөттөн чыгаруу үлгүсү"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"сырсөз"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 405883c..8980dfc 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"ອະນຸຍາດ​ໃຫ້​ແອັບພລິເຄຊັນ​ຈັດຫາ ແລະ​ນຳໃຊ້​ໃບຮັບຮອງ DRM. ແອັບຯ​ທຳມະດາ​ບໍ່​ຄວນ​ຕ້ອງ​ການ​ໃຊ້."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"ຮັບ​ສະ​ຖາ​ນະ​ການ​ໂອນ​ຂໍ້​ມູນ Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບ​ພລິ​ເຄ​ຊັນ​ນີ້​ຮັບ​ຂໍ້​ມູນ​ກ່ຽວ​ກັບ​ການ​ໂອນ​ຂໍ້​ມູນ Android Beam ໃນ​ປັດ​ຈຸ​ບັນ"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"ຕັ້ງຄ່າກົດຂອງລະຫັດຜ່ານ"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"ຄວບຄຸມຄວາມຍາວຂອງໂຕອັກສອນທີ່ສາມາດໃຊ້ກັບລະຫັດປົດລັອກໜ້າຈໍ"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ຕິດຕາມການພະຍາຍາມປົດລັອກໜ້າຈໍ"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"ຟໍແມັດ"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"ເຊື່ອມຕໍ່ການດີບັ໊ກຜ່ານ USB ແລ້ວ"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"ແຕະເພື່ອປິດການດີບັ໊ກຜ່ານ USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"ເລືອກຮູບແບບການປ້ອນ"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"ຕັ້ງຄ່າວິທີການປ້ອນຂໍ້ມູນ"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"ແປ້ນພິມແທ້"</string>
     <string name="hardware" msgid="7517821086888990278">"ຮາດແວ"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"ເລືອກຮູບແບບແປ້ນພິມ"</string>
@@ -1384,11 +1390,11 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນສາມາດຄວບຄຸມຄີກາດໄດ້."</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"​ຕິດ​ຕາມ​ການ​ປ່ຽນ​ແປງ​ສະ​ຖາ​ນະ​ການ​ເຊື່ອ​ຖືກ."</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບ​ພ​ລິ​ເຄ​ຊັນ​ຕິດ​ຕາມ​​ການ​ປ່ຽນ​ແປງ​ໃນ​ສະ​ຖາ​ນະ​ການ​ເຊື່ອ​ຖື."</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"​ລະ​ບຸ​ເອ​ເຈນ​ທີ່​ເຊື່ອ​ຖື​ໄດ້."</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບ​ພ​ລິ​ເຄ​ຊັນ​ລະ​ບຸ​ເອ​ເຈນ​ທີ່​ເຊື່ອ​ຖື​ໄດ້."</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"ເປີດ​ການ​ຕັ້ງ​ຄ່າ​ເມ​ນູເອ​ເຈນ​ທີ່​ເຊື່ອ​ຖື​ໄດ້."</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"​ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບ​ພລິ​ເຄ​ຊັນເປີດ​ການ​ເຄື່ອນ​ໄຫວ​ທີ່​ປ່ຽນ​ພຶດ​ຕິ​ກຳ​ຂອງ​ເອ​ເຈນ."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"​ເຊື່ອມ​ໂຍງ​ຫາ​ບໍ​ລິ​ການ​ຕົວ​ແທນ​ການ​ເຊື່ອ​ຖື"</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"ລະບຸ​ຕົວແທນ​ທີ່ເຊື່ອ​ຖື​ໄດ້."</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບ​ພ​ລິ​ເຄ​ຊັນ​ລະ​ບຸ​ຕົວແທນ​ທີ່​ເຊື່ອ​ຖື​ໄດ້."</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"ເປີດ​ການ​ຕັ້ງ​ຄ່າ​ເມ​ນູຕົວແທນ​ທີ່​ເຊື່ອ​ຖື​ໄດ້."</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"​ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບ​ພລິ​ເຄ​ຊັນເປີດ​ການ​ເຄື່ອນ​ໄຫວ​ທີ່​ປ່ຽນ​ພຶດ​ຕິ​ກຳ​ຂອງ​ຕົວ​ແທນທີ່​ເຊື່ອ​ຖື​ໄດ້."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"​ເຊື່ອມ​ໂຍງ​ຫາ​ບໍ​ລິ​ການ​ຕົວ​ແທນ​​ທີ່​ເຊື່ອຖື​ໄດ້"</string>
     <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"​ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບ​ພ​ລິ​ເຄ​ຊັນເຊື່ອມ​ໂຍງ​ກັບ​ບໍ​ລິ​ການ​ຕົວ​ແທນ​ທີ່​ເຊື່ອ​ຖື​ໄດ້."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"ຕິດຕໍ່ກັບລະບົບອັບເດດ ແລະລະບົບກູ້ຂໍ້ມູນ."</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນຕິດຕໍ່ກັບລະບົບກູ້ຂໍ້ມູນ ແລະການອັບເດດລະບົບ."</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"ຜູ່ໃຊ້ປັດຈຸບັນ <xliff:g id="NAME">%1$s</xliff:g> ."</string>
     <string name="owner_name" msgid="2716755460376028154">"ເຈົ້າຂອງ"</string>
     <string name="error_message_title" msgid="4510373083082500195">"ຜິດພາດ"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"​ຜູ່​ເບິ່ງ​ແຍງ​ລະ​ບົບ​ຂອງ​ທ່ານບໍ່​ອະ​ນຸ​ຍາດ​ໃຫ້​ປ່ຽນ​ແປງ​ສິ່ງ​ນີ້"</string>
     <string name="app_not_found" msgid="3429141853498927379">"ບໍ່ພົບແອັບພລິເຄຊັນເພື່ອຈັດການເຮັດວຽກນີ້."</string>
     <string name="revoke" msgid="5404479185228271586">"ຖອນ"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"ຮູບແບບປົດລັອກ"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"​ລະ​ຫັດ​ຜ່ານ"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index be4f0e0..441dafa 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Programai leidžiama pasiekti ir naudoti DRM sertifikatus. Neturėtų prireikti naudojant įprastas programas."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Gauti „Android“ perdavimo funkcijos perkėlimo būseną"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Programai leidžiama gauti informaciją apie dabartinius „Android“ perdavimo funkcijos perkėlimus"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nustatyti slaptažodžio taisykles"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Valdyti leidžiamą ekrano atrakinimo slaptažodžių ilgį ir leidžiamus naudoti simbolius."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Stebėti bandymus atrakinti ekraną"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatuoti"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB derinimas prijungtas"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Palieskite, kad neleistumėte USB derinimo."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Pasirinkite įvesties metodą"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Nustatyti įvesties metodus"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fizinė klaviatūra"</string>
     <string name="hardware" msgid="7517821086888990278">"Apar. įr."</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Pasirinkite klaviatūros išdėstymą"</string>
@@ -1388,8 +1394,8 @@
     <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Programai leidžiama teikti patikimos priemonės paslaugą."</string>
     <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Paleisti patikimos priemonės nustatymų meniu."</string>
     <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Programai leidžiama paleisti veiklą, keičiančią patikimos priemonės elgseną."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Susisaistyti su „trust agent“ paslauga"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Programai leidžiama susisaistyti su „trust agent“ paslauga."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Susisaistyti su patikimos priemonės paslauga"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Programai leidžiama susisaistyti su patikimos priemonės paslauga."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Sąveikauti su naujiniu ir atkūrimo sistema"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Programai leidžiama sąveikauti su atkūrimo sistema ir sistemos naujiniais."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Kurti medijos projekcijų seansus"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Dabartinis naudotojas: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Savininkas"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Klaida"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Administratorius neleidžia atlikti šio pakeitimo"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nerasta programa šiam veiksmui apdoroti"</string>
     <string name="revoke" msgid="5404479185228271586">"Anuliuoti"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN kodas"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"atrakinimo piešinys"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"slaptažodis"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index e2b2e5b..2de9fc6 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Ļauj lietojumprogrammai nodrošināt un izmantot digitālā satura tiesību pārvaldības sertifikātus. Parastām lietotnēm šī atļauja nekad nav nepieciešama."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Saņemt Android Beam pārsūtīšanas statusu"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Ļauj šai lietojumprogrammai saņemt informāciju par pašreizēju Android Beam pārsūtīšanu"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Paroles kārtulu iestatīšana"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolē ekrāna atbloķēšanas parolē atļautās rakstzīmes un garumu."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Ekrāna atbloķēšanas mēģinājumu pārraudzīšana"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatēt"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB atkļūdošana ir pievienota."</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Pieskarieties, lai atspējotu USB atkļūdošanu."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Ievades metodes izvēle"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Iestatīt ievades metodes"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fiziskā tastatūra"</string>
     <string name="hardware" msgid="7517821086888990278">"Aparatūra"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Atlasiet tastatūras izkārtojumu"</string>
@@ -1388,8 +1394,8 @@
     <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Ļauj lietojumprogrammai nodrošināt uzticamības pārbaudes programmu."</string>
     <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Palaist uzticamības pārbaudes programmas iestatījumu izvēlni."</string>
     <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Ļauj lietojumprogrammai palaist darbību, kas maina uzticamības pārbaudes programmas rīcību."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Izveidot savienojumu ar uzticamības pārbaudes pakalpojumu"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Ļauj lietojumprogrammai izveidot savienojumu ar uzticamības pārbaudes pakalpojumu."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Izveidot savienojumu ar uzticamības pārbaudes programmu"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Ļauj lietojumprogrammai izveidot savienojumu ar uzticamības pārbaudes programmu."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Mijiedarbošanās ar atjauninājumu un atkopšanas sistēmu"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Ļauj lietojumprogrammai mijiedarboties ar atkopšanas sistēmu un sistēmas atjauninājumiem."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Izveidot satura projekcijas sesijas"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Pašreizējais lietotājs: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Īpašnieks"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Kļūda"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Jūsu administrators neļauj veikt šīs izmaiņas."</string>
     <string name="app_not_found" msgid="3429141853498927379">"Netika atrasta neviena lietojumprogramma, kas var veikt šo darbību."</string>
     <string name="revoke" msgid="5404479185228271586">"Atsaukt"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN kods"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"grafiskā atslēga"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"parole"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index 6df89fc..bf2522a 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Дозволува апликацијата да обезбедува и користи ДРМ-сертификати. Не треба да се користи за стандардни апликации."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Примајте статус на трансфер на Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Ѝ дозволува на оваа апликација да добива информации за моменталните трансфери на Android Beam"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Подеси правила за лозинката"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролирај ги должината и знаците што се дозволени за лозинки за отклучување екран."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Следи ги обидите за отклучување на екранот"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Форматирај"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Поврзано е отстранување грешки преку УСБ"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Допрете за да се оневозможи отстранувањето грешки преку USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Одбери метод на внес"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Постави методи на внес"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Физичка тастатура"</string>
     <string name="hardware" msgid="7517821086888990278">"Хардвер"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Избери изглед на тастатура"</string>
@@ -1635,8 +1641,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Тековен корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Сопственик"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Грешка"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Администраторот не ја дозволува промената"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Не се пронајдени апликации да се изврши ова дејство"</string>
     <string name="revoke" msgid="5404479185228271586">"Отповикај"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1767,4 +1772,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"ПИН"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"шема за отклучување"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"лозинка"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 8415ef5..5722300 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"പ്രൊവിഷൻ ചെയ്യുന്നതിനും DRM സർട്ടിഫിക്കറ്റുകൾ ഉപയോഗിക്കുന്നതിനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. സാധാരണ അപ്ലിക്കേഷനുകൾക്ക് ഒരിക്കലും ആവശ്യമില്ല."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android ബീം കൈമാറൽ നില നേടുക"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"നിലവിലെ Android ബീം കൈമാറ്റങ്ങളെക്കുറിച്ച് വിവരങ്ങൾ നേടാൻ ഈ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"പാസ്‌വേഡ് നിയമങ്ങൾ സജ്ജീകരിക്കുക"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"സ്‌ക്രീൻ-അൺലോക്ക് പാസ്‌വേഡുകളിൽ അനുവദിച്ചിരിക്കുന്ന ദൈർഘ്യവും പ്രതീകങ്ങളും നിയന്ത്രിക്കുക."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"സ്‌ക്രീൻ അൺലോക്ക് ശ്രമങ്ങൾ നിരീക്ഷിക്കുക"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"ഫോർമാറ്റുചെയ്യുക"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ഡീബഗ്ഗിംഗ് കണക്‌റ്റുചെയ്‌തു"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ഡീബഗ്ഗിംഗ് പ്രവർത്തനരഹിതമാക്കാൻ സ്‌പർശിക്കുക."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"ഇൻപുട്ട് രീതി തിരഞ്ഞെടുക്കുക"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"ടൈപ്പുചെയ്യൽ രീതികൾ സജ്ജീകരിക്കുക"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"ഭൗതിക കീബോർഡ്"</string>
     <string name="hardware" msgid="7517821086888990278">"ഹാർഡ്‌വെയർ"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"കീബോർഡ് ലേഔട്ട് തിരഞ്ഞെടുക്കുക"</string>
@@ -1386,10 +1392,10 @@
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"വിശ്വസ്‌ത സ്റ്റേറ്റിലെ മാറ്റങ്ങൾ കേൾക്കുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"ഒരു പരിചിത ഏജന്റിനെ നൽകുക."</string>
     <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"ഒരു പരിചിത ഏജന്റിനെ നൽകാൻ ഒരു അപ്ലിക്കേഷൻ അനുവദിക്കുന്നു."</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"വിശ്വസ്ത ഏജന്റ് ക്രമീകരണ മെനു സമാരംഭിക്കുക."</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"വിശ്വസ്ത ഏജന്റിന്റെ പ്രവർത്തനരീതിയെ മാറ്റുന്ന, ഒരു പ്രവർത്തനം സമാരംഭിക്കാൻ ഒരു അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"വിശ്വസ്ത ഏജന്റ് സേവനവുമായി ബന്ധിപ്പിക്കുക"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"ഒരു വിശ്വസ്‌ത ഏജന്റ് സേവനത്തിലേക്ക് ബന്ധിപ്പിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"പരിചിത ഏജന്റ് ക്രമീകരണ മെനു സമാരംഭിക്കുക."</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"പരിചിത ഏജന്റിന്റെ പ്രവർത്തനരീതിയെ മാറ്റുന്ന, ഒരു പ്രവർത്തനം സമാരംഭിക്കാൻ ഒരു അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"പരിചിത ഏജന്റ് സേവനവുമായി ബന്ധിപ്പിക്കുക"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"ഒരു പരിചിത ഏജന്റ് സേവനത്തിലേക്ക് ബന്ധിപ്പിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"അപ്‌ഡേറ്റ്, വീണ്ടെടുക്കൽ സിസ്റ്റവുമായി സംവദിക്കുക"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"വീണ്ടെടുക്കൽ സിസ്റ്റവുമായും സിസ്റ്റം അപ്‌ഡേറ്റുകളുമായും സംവദിക്കാൻ ഒരു അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"മീഡിയ പ്രൊജക്ഷൻ സെഷനുകൾ സൃഷ്‌ടിക്കുക"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"നിലവിലെ ഉപയോക്താവ് <xliff:g id="NAME">%1$s</xliff:g> ആണ്."</string>
     <string name="owner_name" msgid="2716755460376028154">"ഉടമ"</string>
     <string name="error_message_title" msgid="4510373083082500195">"പിശക്"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"ഈ മാറ്റം നിങ്ങളുടെ അഡ്‌മിനിസ്‌ട്രേറ്റർ അനുവദിച്ചതല്ല"</string>
     <string name="app_not_found" msgid="3429141853498927379">"ഈ പ്രവർത്തനം കൈകാര്യം ചെയ്യുന്ന അപ്ലിക്കേഷനുകളൊന്നും കണ്ടെത്തിയില്ല"</string>
     <string name="revoke" msgid="5404479185228271586">"റദ്ദാക്കുക"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"പിൻ"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"അൺലോക്ക് പാറ്റേൺ"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"പാസ്‌വേഡ്"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 8236bf8..1588426 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Аппликешнд DRM сертификатыг ашиглах болон нийлүүлэхийг зөвшөөрнө. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Андройд Бийм дамжуулалтын статусыг хүлээн авах"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Одоогийн Андройд Бийм дамжуулалтын мэдээллийг хүлээн авахыг аппликешнд зөвшөөрөх"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Нууц үгний дүрмийг тохируулах"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Дэлгэц түгжих нууц үгэнд зөвшөөрөгдсөн тэмдэгт болон уртыг удирдах"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Дэлгэц тайлах оролдлогыг хянах"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Форматлах"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB дебаг холбогдсон"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB дебаг хийхийг идэвхгүй болгох бол хүрнэ үү."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Оруулах аргыг сонгоно уу"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Оруулах аргыг тохируулах"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Бодит гар"</string>
     <string name="hardware" msgid="7517821086888990278">"Хардвер"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Гарын схемийг сонгох"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Одоогийн хэрэглэгч <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Эзэмшигч"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Алдаа"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Энэ өөрчлөлтийг админ зөвшөөрөөгүй байна"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Энэ ажиллагааг зохицуулах аппликешн олдсонгүй."</string>
     <string name="revoke" msgid="5404479185228271586">"Цуцлах"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"тайлах хээ"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"нууц үг"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 15310ec..33aaed8 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"DRM प्रमाणपत्रांची तरतूद करण्यासाठी आणि वापरण्यासाठी अनुप्रयोगास अनुमती देते. सामान्य अॅप्सकरिता कधीही आवश्यकता नसते."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android बीम स्थानांतरण स्थिती प्राप्त करा"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"वर्तमान Android बीम स्थानांतरणांविषयी माहिती प्राप्त करण्यासाठी या अनुप्रयोगास अनुमती देते"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"संकेतशब्द नियम सेट करा"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"स्क्रीन-अनलॉक संकेतशब्दांमध्ये अनुमती दिलेली लांबी आणि वर्ण नियंत्रित करा."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"स्क्रीन-अनलॉक प्रयत्नांचे परीक्षण करा"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"फॉरमॅट करा"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग करणे कनेक्‍ट केले"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB डीबग करणे अक्षम करण्यासाठी स्पर्श करा."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"इनपुट पद्धत निवडा"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"इनपुट पद्धती सेट करा"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"वास्तविक कीबोर्ड"</string>
     <string name="hardware" msgid="7517821086888990278">"हार्डवेअर"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"कीबोर्ड लेआउट निवडा"</string>
@@ -1385,7 +1391,7 @@
     <string name="permlab_trust_listener" msgid="1765718054003704476">"विश्वास स्थितीतील बदल ऐका."</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"विश्वास स्थितीमधील बदल ऐकण्यासाठी अनुप्रयोगास अनुमती देते."</string>
     <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"एक विश्वासू एजंट प्रदान करा."</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"अनुप्रयोगास ट्रस्ट एजंट प्रदान करण्यासाठी अनुप्रयोगास अनुमती देते."</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"विश्वासू एजंट प्रदान करण्यासाठी अनुप्रयोगास अनुमती देते."</string>
     <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"विश्वासू एजंट सेटिंग्‍ज मेनू लाँच करा."</string>
     <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"विश्वासू एजंट वर्तन बदलणारा क्रियाकलाप लाँच करण्यासाठी अनुप्रयोगास अनुमती देते."</string>
     <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"विश्वासू एजंट सेवेवर प्रतिबद्ध करा"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"वर्तमान वापरकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"मालक"</string>
     <string name="error_message_title" msgid="4510373083082500195">"त्रुटी"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"या बदलास आपल्या प्रशासकाकडून अनुमती नाही"</string>
     <string name="app_not_found" msgid="3429141853498927379">"ही क्रिया हाताळण्यासाठी कोणताही अनुप्रयोग आढळला नाही"</string>
     <string name="revoke" msgid="5404479185228271586">"मागे घ्‍या"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"अनलॉक नमुना"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"संकेतशब्द"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index caa6e32..ea6e3a8 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Membenarkan aplikasi memperuntuk dan menggunakan sijil DRM. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Terima status pemindahan Pancaran Android"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Membenarkan aplikasi ini menerima maklumat mengenai pemindahan Pancaran Android semasa"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Tetapkan peraturan kata laluan"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Mengawal panjang dan aksara yang dibenarkan dalam kata laluan buka kunci skrin."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Memantau percubaan buka kunci skrin"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Penyahpepijatan USB disambungkan"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Sentuh untuk melumpuhkan penyahpepijatan USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Pilih kaedah input"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Sediakan kaedah input"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Papan kekunci fizikal"</string>
     <string name="hardware" msgid="7517821086888990278">"Perkakasan"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Pilih susun atur papan kekunci"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Pengguna semasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Pemilik"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Ralat"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Perubahan ini tidak dibenarkan oleh pentadbir anda"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Tidak menemui aplikasi untuk mengendalikan tindakan ini"</string>
     <string name="revoke" msgid="5404479185228271586">"Batalkan"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"corak buka kunci"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"kata laluan"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 7047bee..4b95048 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"အပလီကေးရှင်း တစ်ခုအား စီမံလုပ်ကိုင်ခွင့် DRM လက်မှတ်များ သုံးခွင့် ပြုသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"အန်ဒရွိုက်၏ အလင်းတန်းထိုး လွှဲပြောင်းမှု အခြေအနေကို ရယူရန်"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"ဒီအပလီကေးရှင်းအား အန်ဒရွိုက်၏ လက်ရှိ အလင်းတန်းထိုး လွှဲပြောင်းမှု အကြောင်း အချက်အလက်ကို ရယူခွင့် ပြုသည်"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"စကားဝှက်စည်းမျဥ်းကိုသတ်မှတ်ရန်"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"မျက်နှာပြင် သော့ဖွင့်ရန် လိုအပ်သော စကားလုံးအရေအတွက်နှင့် အမျိုးအစားအား ထိန်းချုပ်ရန်"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"မော်နီတာမျက်နှာပြင်ဖွင့်ရန် ကြိုးစားခွင့်များ"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"ပုံစံချရန်ပြင်ဆင်သည်"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB အမှားစစ်ခြင်းအား ချိတ်ဆက်ထားသည်"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ဒီဘာဂင် ပိတ်ရန် ထိပါ။"</string>
-    <string name="select_input_method" msgid="4653387336791222978">"ထည့်သွင်းရေး နည်းကို ရွေးရန်"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"ရိုက်ထည့် နည်းများ သတ်မှတ်ရန်"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"ခလုတ်ပါဝင်သော ကီးဘုတ်"</string>
     <string name="hardware" msgid="7517821086888990278">"ဟာ့ဒ်ဝဲ"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"လက်ကွက် အပြင်အဆင်ရွေးရန်"</string>
@@ -1764,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"သော့ဖွင့် ပုံစံဒီဇိုင်း"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"စကားဝှက်"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index a669ee3..f73ec3c 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Tillater at en app klargjøre og bruke DRM-sertifikater. Denne tillatelsen bør aldri være nødvendig for vanlige apper."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Motta overføringsstatus for Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Lar appen motta informasjon om aktuelle Android Beam-overføringer"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Angi passordregler"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontroller tillatt lengde og tillatte tegn i passord for opplåsing av skjerm."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Overvåk forsøk på opplåsing av skjerm"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatér"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-debugging tilkoblet"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Trykk for å deaktivere USB-feilsøking."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Velg inndatametode"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Konfigurer inndatametoder"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fysisk tastatur"</string>
     <string name="hardware" msgid="7517821086888990278">"Maskinvare"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Velg tastaturoppsett"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Gjeldende bruker: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Eier"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Feil"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Denne endringen er ikke tillatt av administratoren"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Finner ingen apper som kan utføre denne handlingen"</string>
     <string name="revoke" msgid="5404479185228271586">"Opphev"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN-kode"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"opplåsingsmønster"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"passord"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index 879e379..18619d1 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"DRM प्रमाणपत्रहरू प्रावधान र प्रयोग गर्ने निवेदनको अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिल्यै पनि आवश्यक पर्दैन।"</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android Beam स्थानान्तरण अवस्था प्राप्त गर्नुहोस्"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"यस आवेदनले वर्तमान Android Beam स्थानान्तरण बारेमा जानकारी प्राप्त गर्न अनुमति दिन्छ"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियमहरू मिलाउनुहोस्"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"स्क्रिन-अनलक पासवर्डहरूमा अनुमति दिइएको लम्बाइ र अक्षरहरू नियन्त्रण गर्नुहोस्।"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"मोनिटर स्क्रिन-अनलक प्रयत्नहरू"</string>
@@ -1347,8 +1351,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"फर्म्याट गर्नुहोस्"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डिबग गर्ने जडित छ"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB डिबग गर्ने असक्षम पार्न छुनुहोस्।"</string>
-    <string name="select_input_method" msgid="4653387336791222978">"निवेश विधि छान्नुहोस्"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"इनपुट विधिहरू सेटअप गर्नुहोस्"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"भौतिक किबोर्ड"</string>
     <string name="hardware" msgid="7517821086888990278">"हार्डवेयर"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"किबोर्ड रूपरेखा चयन गर्नुहोस्"</string>
@@ -1641,8 +1647,7 @@
     <string name="user_switched" msgid="3768006783166984410">"अहिलेको प्रयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>।"</string>
     <string name="owner_name" msgid="2716755460376028154">"मालिक"</string>
     <string name="error_message_title" msgid="4510373083082500195">"त्रुटि"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"यो परिवर्तन गर्न तपाईँको प्रशासक द्वारा अनुमति छैन"</string>
     <string name="app_not_found" msgid="3429141853498927379">"यस कार्य सम्हालने कुनै अनुप्रयोग भेटिएन"</string>
     <string name="revoke" msgid="5404479185228271586">"रद्द गर्नुहोस्"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1775,4 +1780,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"शैली बन्द गर्नुहोस"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"पासवर्ड"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 1916f0e..7a638ab 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Toestaan dat een app DRM-certificaten registreert en gebruikt. Nooit vereist voor normale apps."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android Beam-overdrachtsstatus ontvangen"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Hiermee kan deze app informatie over huidige Android Beam-overdrachten ontvangen"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Wachtwoordregels instellen"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"De lengte en tekens beheren die zijn toegestaan in wachtwoorden voor schermontgrendeling."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Pogingen voor schermontgrendeling bijhouden"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatteren"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-foutopsporing verbonden"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Tik om USB-foutopsporing uit te schakelen."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Invoermethode selecteren"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Invoermethoden instellen"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fysiek toetsenbord"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Toetsenbordindeling selecteren"</string>
@@ -1384,12 +1390,12 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Staat toe dat een app de toetsbeveiliging beheert."</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"Controleren op wijzigingen in de trust-status."</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"Toestaan dat een app controleert op wijzigingen in de trust-status."</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Een trust-agent aanleveren."</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Hiermee kan een app een trust-agent aanleveren."</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Menu met instellingen voor trust-agents starten."</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Hiermee kan een app een activiteit starten waarmee het gedrag van trust-agents wordt gewijzigd."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Binden aan een trust-agentservice"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Toestaan dat een app wordt gebonden aan een trust-agentservice."</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Een trust agent aanleveren."</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Hiermee kan een app een trust agent aanleveren."</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Menu met instellingen voor trust agents starten."</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Hiermee kan een app een activiteit starten waarmee het gedrag van trust agents wordt gewijzigd."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Binden aan een trust agent-service"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Toestaan dat een app wordt gebonden aan een trust agent-service."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Interactie met update- en herstelsysteem"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Hiermee kan een app interactie hebben met het herstelsysteem en systeemupdates."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Mediaprojectiesessies maken"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Eigenaar"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Fout"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Deze wijziging is niet toegestaan door uw beheerder"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Er is geen app gevonden om deze actie uit te voeren"</string>
     <string name="revoke" msgid="5404479185228271586">"Intrekken"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"pincode"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"ontgrendelingspatroon"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"wachtwoord"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index bae26f8..964ac3b 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Zezwala aplikacji na dodanie i używanie certyfikatów DRM. Nieprzeznaczone dla zwykłych aplikacji."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Uzyskiwanie informacji o stanie transmisji Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Zezwala tej aplikacji na otrzymywanie informacji o aktualnych transmisjach Android Beam"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Określ reguły hasła"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolowanie długości haseł odblokowania ekranu i dozwolonych w nich znaków"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitoruj próby odblokowania ekranu"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatuj"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Podłączono moduł debugowania USB"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotknij, aby wyłączyć debugowanie USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Wybierz metodę wprowadzania"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Konfiguruj metody wprowadzania"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Klawiatura fizyczna"</string>
     <string name="hardware" msgid="7517821086888990278">"Sprzęt"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Wybierz układ klawiatury"</string>
@@ -1384,11 +1390,11 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Umożliwia aplikacji kontrolowanie zabezpieczenia kluczami."</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"Monitoruj zmiany w stanie zaufania."</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"Zezwala aplikacji na monitorowanie zmian w stanie zaufania."</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Dostarczaj agenta zaufania."</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Dostarczanie agenta zaufania"</string>
     <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Zezwala aplikacji na dostarczanie agenta zaufania."</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Otwieranie menu ustawień agenta zaufania."</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Otwieranie menu ustawień agenta zaufania"</string>
     <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Zezwala aplikacji na uruchamianie akcji, która zmienia sposób działania agenta zaufania."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Powiąż z usługą agenta zaufania"</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Powiązanie z usługą agenta zaufania"</string>
     <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Zezwala aplikacji na powiązanie z usługą agenta zaufania."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Interakcja z systemem odzyskiwania i aktualizacjami"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Zezwala aplikacji na interakcję z systemem odzyskiwania i aktualizacjami systemu."</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Bieżący użytkownik: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Właściciel"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Błąd"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Ta zmiana nie jest dozwolona przez administratora"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nie znaleziono aplikacji do obsługi tej akcji"</string>
     <string name="revoke" msgid="5404479185228271586">"Cofnij"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"Kod PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"wzór odblokowania"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"hasło"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 0341db8..0f93ee0 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permite que uma aplicação forneça e utilize certificados DRM. Nunca deverá ser necessário para aplicações normais."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Receber estado de transferência do Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Permite que esta aplicação receba informações acerca das transferências atuais do Android Beam"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras de palavra-passe"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar o comprimento e os caracteres permitidos nas palavras-passe de desbloqueio do ecrã."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizar tentativas de desbloqueio do ecrã"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatar"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toque para desativar a depuração USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Escolher o método de entrada"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Configurar métodos de introdução"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Teclado físico"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selecionar esquema de teclado"</string>
@@ -1388,8 +1394,8 @@
     <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Permite que uma aplicação forneça um agente fidedigno."</string>
     <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Iniciar o menu de definições do agente fidedigno."</string>
     <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Permite que uma aplicação inicie uma atividade que altere o comportamento do agente fidedigno."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Vincular a um serviço de trust agent"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Permite que uma aplicação fique vinculada a um serviço de trust agent."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Vincular a um serviço de agente fidedigno"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Permite que uma aplicação fique vinculada a um serviço de agente fidedigno."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Interagir com o sistema de recuperação e de atualização"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Permite que uma aplicação interaja com o sistema de recuperação e as atualizações do sistema."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Criar sessões de projeção multimédia"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> do utilizador atual."</string>
     <string name="owner_name" msgid="2716755460376028154">"Proprietário"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Erro"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"O administrador não permite esta alteração"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Não foram encontradas aplicações para executar esta ação"</string>
     <string name="revoke" msgid="5404479185228271586">"Revogar"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"sequência de desbloqueio"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"palavra-passe"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 169498a..eb9d4da 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permite que o aplicativo provisione e use certificados de DRM. Não deve ser necessário para aplicativos comuns."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Receber status de transferência do Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Permite que este aplicativo receba informações sobre as atuais transferências do Android Beam"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras para senha"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar o tamanho e os caracteres permitidos nas senhas de desbloqueio de tela."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorar tentativas de desbloqueio da tela"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatar"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toque para desativar a depuração do USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Selecione o método de entrada"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Configurar métodos de entrada"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Teclado físico"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selecione o layout de teclado"</string>
@@ -1386,7 +1392,7 @@
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"Permite que o aplicativo detecte alterações no estado de confiança."</string>
     <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Fornecer um agente de confiança."</string>
     <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Permite que um aplicativo forneça um agente de confiança."</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Abra o menu de configurações do agente de confiança."</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Abrir o menu de configurações do agente de confiança."</string>
     <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Permite que um aplicativo inicie uma atividade que altera o comportamento do agente de confiança."</string>
     <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Associar a um serviço de agente de confiança"</string>
     <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Permite que o aplicativo se associe a um serviço de agente de confiança."</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Proprietário"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Erro"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Esta alteração não é permitida pelo administrador"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nenhum aplicativo encontrado para executar a ação"</string>
     <string name="revoke" msgid="5404479185228271586">"Revogar"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"desbloquear padrão"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"senha"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index d2d4c34..8bb23d4 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -741,6 +741,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permite unei aplicații să furnizeze și să utilizeze certificate DRM. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Primiți starea transferului prin Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Permite acestei aplicații să primească informații despre transferurile actuale Android Beam"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Setaţi reguli pentru parolă"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Stabiliţi lungimea şi tipul de caractere permise în parolele pentru deblocarea ecranului."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizaţi încercările de deblocare a ecranului"</string>
@@ -1341,8 +1345,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formataţi"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depanarea USB este conectată"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Atingeţi pentru a dezactiva depanarea USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Alegeți metoda de introducere de text"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Setați metode introducere text"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Tastatură fizică"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selectaţi aspectul tastaturii"</string>
@@ -1635,8 +1641,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Utilizator curent: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Proprietar"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Eroare"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Această modificare nu este permisă de administratorul dvs."</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nicio aplicație pentru gestionarea acestei acțiuni"</string>
     <string name="revoke" msgid="5404479185228271586">"Revocați"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1767,4 +1772,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"model pentru deblocare"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"parolă"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 78f7703..dc05a64 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Приложение сможет синхронизировать и использовать сертификаты DRM (разрешение актуально только для специальных приложений)."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Получение статуса передачи Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Получение информации о текущих передачах Android Beam."</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Правила выбора паролей"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролировать длину и символы при вводе паролей для снятия блокировки экрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Отслеживать попытки снятия блокировки экрана"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Формат"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отладка по USB разрешена"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Нажмите, чтобы отключить отладку по USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Выберите способ ввода"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Настройка способов ввода"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Физическая клавиатура"</string>
     <string name="hardware" msgid="7517821086888990278">"Аппаратура"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Выберите раскладку клавиатуры"</string>
@@ -1384,12 +1390,12 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Приложение сможет управлять хранилищем ключей."</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"Отслеживание изменений статуса доверия"</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"Приложение сможет отслеживать изменения в статусе доверия."</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Доверенный агент"</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Предоставление доверенных агентов."</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Запуск настроек Trust Agent"</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Запуск меню, позволяющего управлять настройками Trust Agent."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Подключение к службе Trust Agents"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Приложение сможет подключаться к службе Trust Agents."</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Предоставление промежуточного агента"</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Приложение может предоставлять промежуточный агент."</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Запуск меню настроек промежуточного агента"</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Приложение может запускать активность, изменяющую поведение промежуточного агента."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Подключение к службе промежуточного агента"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Приложение может подключаться к службе промежуточного агента."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Взаимодействовать с системой восстановления и обновлениями"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Приложение сможет взаимодействовать с системой восстановления и обновлениями системы."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Создание сеансов трансляции контента"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Выбран аккаунт пользователя <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Владелец"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Ошибка"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Это действие запрещено администратором"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Невозможно обработать это действие"</string>
     <string name="revoke" msgid="5404479185228271586">"Отменить"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0 (841 х 1189 мм)"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN-код"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"графический ключ"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"пароль"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index eff02b3..ebf6fd1 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"යෙදුමකට DRM  සහතික වෙන් කර භාවිතා කිරීමට ඉඩ දේ. සාමාන්‍ය යෙදුම් වලට කිසිදා අවශ්‍ය නොවේ."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android බීම් හුවමාරු තත්ත්වය ලබාගන්න"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"දැනට තිබෙන Android බීම් හුවමාරු පිළිබඳ තොරතුරු ලබාගැනීමට මෙම යෙදුමට ඉඩ දෙන්න"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"මුරපද නීති සකස් කිරීම"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"තිරය අගුළු ඇරීමේ මුරපදයට අනුමත අකුරු සහ දිග පාලනය කරන්න."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"තිරය අගුළු ඇරීමේ උත්සාහයන් නිරීක්ෂණය කරන්න"</string>
@@ -1342,8 +1346,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"ෆෝමැට්"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB නිදොස්කරණය සම්බන්ධිතයි"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB නිදොස්කරණය අබල කිරීමට ස්පර්ශ කරන්න."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"ආදාන ක්‍රමයක් තෝරන්න"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"ආදාන ක්‍රම සකසන්න"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"භෞතික යතුරු පුවරුව"</string>
     <string name="hardware" msgid="7517821086888990278">"දෘඨාංග"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"යතුරු පුවරුවට පිරිසැලැස්ම තෝරන්න"</string>
@@ -1636,8 +1642,7 @@
     <string name="user_switched" msgid="3768006783166984410">"දැනට සිටින පරිශීලකයා <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"හිමිකරු"</string>
     <string name="error_message_title" msgid="4510373083082500195">"දෝෂය"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"ඔබගේ පරිපාලක විසින් මෙම වෙනස් කිරීමට ඉඩ නොදේ"</string>
     <string name="app_not_found" msgid="3429141853498927379">"මෙම ක්‍රියාව හසුරුවීමට යෙදුමක් සොයාගත්තේ නැත"</string>
     <string name="revoke" msgid="5404479185228271586">"අහෝසි කරන්න"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1768,4 +1773,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"අඟුළු ඇරීමේ රටාව"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"මුරපදය"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 2868477..1ff9503 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Umožňuje aplikácii vydávať a používať certifikáty DRM. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Prijímať stav prenosu funkcie Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Povoľuje tejto aplikácii prijímať informácie o aktuálnych prenosoch funkcie Android Beam"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastaviť pravidlá pre heslo"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Ovládanie dĺžky hesiel na odomknutie obrazovky a v nich používané znaky."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Sledovať pokusy o odomknutie obrazovky"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formát"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladenie cez USB pripojené"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotknutím zakážete ladenie USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Zvoliť metódu vstupu"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Nastavenie metód vstupu"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fyzická klávesnica"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardvér"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Zvoľte rozloženie klávesnice"</string>
@@ -1384,12 +1390,12 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Umožňuje aplikácii ovládať technológiu keyguard."</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"Reagovanie na zmeny stavu dôveryhodnosti."</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"Umožňuje aplikácii reagovať na zmeny stavu dôveryhodnosti."</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Poskytnúť dôveryhodného agenta"</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Umožňuje aplikácii poskytnúť dôveryhodného agenta."</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Spustiť ponuku nastavení agenta dôveryhodnosti"</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Umožňuje aplikácii spustiť aktivitu, ktorá zmení správanie agenta dôveryhodnosti."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Viazanie sa na službu zástupcu dôveryhodnosti"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Umožňuje aplikácii viazať sa na službu zástupcu dôveryhodnosti."</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Poskytovať agenta dôvery"</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Umožňuje aplikácii poskytovať agenta dôvery."</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Spustiť ponuku nastavení agenta dôvery"</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Umožňuje aplikácii spustiť aktivitu, ktorá zmení správanie agenta dôvery."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Viazať sa na službu agenta dôvery"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Umožňuje aplikácii viazať sa na službu agenta dôvery."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Interakcia so systémom aktualizácií a obnovenia"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Umožňuje aplikácii interakciu so systémom obnovenia a s aktualizáciami systému."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Vytváranie relácií projekcie médií"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Aktuálny používateľ je <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Vlastník"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Chyba"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Správca túto zmenu zakázal"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Aplikácia potrebná na spracovanie tejto akcie sa nenašla"</string>
     <string name="revoke" msgid="5404479185228271586">"Odvolať"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"Číslo PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"bezpečnostný vzor"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"heslo"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 50768cd..551aa39 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Aplikaciji omogoča pripravo in uporabo potrdil za upravljanje digitalnih pravic. To naj ne bi bilo nikoli potrebno za običajne aplikacije."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Prejemanje stanja prenosov s funkcijo Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Omogoči tej aplikaciji prejemanje podatkov o trenutnih prenosih s funkcijo Android Beam"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavitev pravil za geslo"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Nadzor nad dolžino in znaki, ki so dovoljeni v geslih za odklepanje zaslona."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"nadzor nad poskusi odklepanja zaslona"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatiraj"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Iskanje in odpravljanje napak USB je povezano"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotaknite se, če želite onemogočiti iskanje in odpravljanje napak prek vrat USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Izberite način vnosa"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Nastavi načine vnosa"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fizična tipkovnica"</string>
     <string name="hardware" msgid="7517821086888990278">"Strojna oprema"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Izberite razporeditev tipkovnice"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Trenutni uporabnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Lastnik"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Napaka"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Skrbnik ne dovoli te spremembe"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Najdena ni bila nobena aplikacija za izvedbo tega dejanja"</string>
     <string name="revoke" msgid="5404479185228271586">"Prekliči"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"vzorec za odklepanje"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"geslo"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index bb46b87..31b137d 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Дозвољава апликацији да додељује и користи DRM сертификате. Никада не би требало да се користи за уобичајене апликације."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Пријем статуса пребацивања помоћу Android пребацивања"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Дозвољава овој апликацији да прима информације о актуелним пребацивањима помоћу Android пребацивања"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Подешавање правила за лозинку"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролишите дужину и знакове дозвољене у лозинкама за откључавање екрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Надгледање покушаја откључавања екрана"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Формат"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отклањање грешака са USB-а је успостављено"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Додирните да бисте онемогућили отклањање грешака са USB-а."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Избор метода уноса"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Подеси методе уноса"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Физичка тастатура"</string>
     <string name="hardware" msgid="7517821086888990278">"Хардвер"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Избор распореда тастатуре"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Актуелни корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Власник"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Грешка"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Администратор није дозволио ову промену"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Није пронађена ниједна апликација која би могла да обави ову радњу"</string>
     <string name="revoke" msgid="5404479185228271586">"Опозови"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"шаблон за откључавање"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"лозинка"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index c8a0cc5..d9032ee 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Tillåter att en app tillhandahåller och använder DRM-certifikat. Behövs inte för vanliga appar."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Ta emot status för Android Beam-överföring"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Tillåter att appen tar emot information om aktuella Android Beam-överföringar"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Ange lösenordsregler"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Bestäm hur många och vilka tecken som är tillåtna i skärmlåsets lösenord."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Övervaka försök att låsa upp skärmen"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-felsökning ansluten"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Tryck om du vill inaktivera USB-felsökning."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Välj inmatningsmetod"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Konfigurera inmatningsmetoder"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fysiskt tangentbord"</string>
     <string name="hardware" msgid="7517821086888990278">"Maskinvara"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Välj en tangentbordslayout"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Nuvarande användare: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Ägare"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Fel"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Administratören tillåter inte den här ändringen"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Ingen app som kan hantera åtgärden hittades"</string>
     <string name="revoke" msgid="5404479185228271586">"Återkalla"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"Pinkod"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"grafiskt lösenord"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"lösenord"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 447bb57..4f14f2a 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Huruhusu programu kwa utoaji na matumizi ya vyeti vya DRM. Havifahi kuhitajika kwa ajili ya programu za kawaida."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Pokea hali ya uhamisho wa Boriti ya Android"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Huruhusu programu hii kupokea taarifa kuhusu uhamisho wa Boriti ya Android"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Kuweka kanuni za nenosiri"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kudhibiti urefu na herufi zinazoruhusiwa katika manenosiri ya kufungua skrini."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Kuhesabu mara ambazo skrini inajaribu kufunguliwa"</string>
@@ -1199,8 +1203,8 @@
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Chagua programu ya kifaa cha USB"</string>
     <string name="noApplications" msgid="2991814273936504689">"Hakuna programu zinazoweza kufanya tendo hili."</string>
     <string name="aerr_title" msgid="1905800560317137752"></string>
-    <string name="aerr_application" msgid="932628488013092776">"Kwa bahati mbaya, <xliff:g id="APPLICATION">%1$s</xliff:g> imekoma."</string>
-    <string name="aerr_process" msgid="4507058997035697579">"Kwa bahati mbaya, mchakato <xliff:g id="PROCESS">%1$s</xliff:g> umekoma."</string>
+    <string name="aerr_application" msgid="932628488013092776">"Kwa bahati mbaya, <xliff:g id="APPLICATION">%1$s</xliff:g> imeacha kufanya kazi."</string>
+    <string name="aerr_process" msgid="4507058997035697579">"Kwa bahati mbaya, mchakato wa <xliff:g id="PROCESS">%1$s</xliff:g> umekoma."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
     <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> haifanyi kazi.\n\nUnataka kuifunga?"</string>
     <string name="anr_activity_process" msgid="5776209883299089767">"Shughuli <xliff:g id="ACTIVITY">%1$s</xliff:g> haijibu. \n\n Unataka kuifunga?"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Fomati"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Utatuaji wa USB umeunganishwa"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Gusa ili uzime utatuaji wa USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Chagua njia ya ingizo"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Weka mbinu za ingizo"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Kibodi halisi"</string>
     <string name="hardware" msgid="7517821086888990278">"Maunzi"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Teua mpangilio wa kibodi"</string>
@@ -1384,12 +1390,12 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Huruhusu programu kudhibiti kilinda-funguo."</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"Sikiliza mabadiliko ya hali ya kuaminiwa."</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"Huruhusu programu kusikiliza mabadiliko katika hali ya kuaminiwa."</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Toa wakala wa uaminifu."</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Huruhusu programu kutoa wakala wa uaminifu."</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Fungua menyu ya mipangilio ya madalali wa kuaminiwa."</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Huruhusu programu kufungua kitendo ambacho hubadilisha tabia ya madalali wa kuaminiwa."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Funga kwenye huduma ya dalali wa kuaminiwa"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Huruhusu programu kufungamanisha kwenye huduma ya dalali wa kuaminiwa."</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Kutoa kipengele cha kutathmini hali ya kuaminika."</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Huruhusu programu kutoa kipengele cha kutathmini hali ya kuaminika."</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Fungua menyu ya mipangilio ya kipengele cha kutathmini hali ya kuaminika."</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Huruhusu programu kuanzisha shughuli ambayo hubadilisha tabia ya kipengele cha kutathmini hali ya kuaminika."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Kujiambatisha kwenye huduma ya kutathmini hali ya kuaminika"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Huruhusu programu kujiambatisha kwenye huduma ya kutathmini hali ya kuaminika."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Ingiliana na sasisho na mfumo wa kurejesha"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Huruhusu programu kuingiliana na mfumo wa kurejesha na sasisho la mfumo."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Unda vipindi vya kuonyesha maudhui"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Mtumiaji wa sasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Mmiliki"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Hitilafu"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Mabadiliko haya hayaruhusiwi na msimamizi wako"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Hakuna programu iliyopatikana ili kushughulikia kitendo hiki"</string>
     <string name="revoke" msgid="5404479185228271586">"Batilisha"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"mchoro wa kufungua"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"nenosiri"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index f09b328..187a644 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"DRM சான்றிதழ்களை வழங்க மற்றும் பயன்படுத்த, பயன்பாட்டை அனுமதிக்கிறது. சாதாரண பயன்பாடுகளுக்கு எப்போதும் தேவைப்படாது."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android பீம் பரிமாற்ற நிலையைப் பெறுக"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"நடப்பு Android பீம் பரிமாற்றங்கள் குறித்த தகவலைப் பெற, பயன்பாட்டை அனுமதிக்கிறது"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"கடவுச்சொல் விதிகளை அமைக்கவும்"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"திரையைத் திறக்க கடவுச்சொற்களில் அனுமதிக்கப்பட்ட நீளத்தையும், எழுத்துக்குறிகளையும் கட்டுப்படுத்தலாம்."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"திரைத் திறக்க முயற்சிகளைக் கண்காணித்தல்"</string>
@@ -1219,7 +1223,7 @@
     <string name="smv_application" msgid="3307209192155442829">"<xliff:g id="APPLICATION">%1$s</xliff:g> பயன்பாடு (செயல்முறை <xliff:g id="PROCESS">%2$s</xliff:g>), தனது சுய-செயலாக்க StrictMode கொள்கையை மீறியது."</string>
     <string name="smv_process" msgid="5120397012047462446">"<xliff:g id="PROCESS">%1$s</xliff:g> செயல்முறை, தனது சுய-செயலாக்க StrictMode கொள்கையை மீறியது."</string>
     <string name="android_upgrading_title" msgid="1584192285441405746">"Android மேம்படுத்தப்படுகிறது…"</string>
-    <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g> பயன்பாட்டை உகப்பாக்குகிறது."</string>
+    <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g> பயன்பாட்டை ஒருங்கிணைக்கிறது."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"பயன்பாடுகள் தொடங்கப்படுகின்றன."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"துவக்குதலை முடிக்கிறது."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> இயங்குகிறது"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"வடிவமைப்பு"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB பிழைதிருத்தம் இணைக்கப்பட்டது"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB பிழைத்திருத்தத்தை முடக்க, தொடவும்."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"உள்ளீட்டு முறையைத் தேர்வுசெய்க"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"உள்ளீட்டு முறைகளை அமை"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"கைமுறை விசைப்பலகை"</string>
     <string name="hardware" msgid="7517821086888990278">"வன்பொருள்"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"விசைப்பலகைத் தளவமைப்பைத் தேர்ந்தெடுக்கவும்"</string>
@@ -1626,15 +1632,14 @@
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"திறப்பதற்கான வடிவத்தை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். மேலும் <xliff:g id="NUMBER_1">%d</xliff:g> தோல்வி முயற்சிகளுக்குப் பிறகு, மின்னஞ்சல் கணக்கைப் பயன்படுத்தி உங்கள் மொபைலைத் திறக்கக் கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"அகற்று"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"பரிந்துரைத்த அளவை விட ஒலியை அதிகரிக்கவா?\n\nநீண்ட நேரத்திற்கு அதிகளவில் ஒலி கேட்பது காதுகளைப் பாதிக்கலாம்."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"பரிந்துரைத்த அளவை விட ஒலியை அதிகரிக்கவா?\n\nநீண்ட நேரத்திற்கு அதிகளவில் ஒலி கேட்பது கேட்கும் திறனைப் பாதிக்கலாம்."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"அணுகல்தன்மையை இயக்க இரண்டு விரல்களைத் தொடர்ந்து வைக்கவும்."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"அணுகல்தன்மை இயக்கப்பட்டது."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"அணுகல்தன்மை ரத்துசெய்யப்பட்டது."</string>
     <string name="user_switched" msgid="3768006783166984410">"நடப்பு பயனர் <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"உரிமையாளர்"</string>
     <string name="error_message_title" msgid="4510373083082500195">"பிழை"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"உங்கள் நிர்வாகி இந்த மாற்றத்தை அனுமதிக்கவில்லை"</string>
     <string name="app_not_found" msgid="3429141853498927379">"இந்தச் செயலைச் செய்ய பயன்பாடு எதுவுமில்லை"</string>
     <string name="revoke" msgid="5404479185228271586">"திரும்பப்பெறு"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"திறப்பதற்கான வடிவம்"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"கடவுச்சொல்"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 19944e6..8e465e7 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"DRM ప్రమాణపత్రాలను కేటాయించడానికి మరియు ఉపయోగించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. సాధారణ అనువర్తనాలకు ఎప్పటికీ అవసరం ఉండదు."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android Beam బదిలీ స్థితిని స్వీకరించండి"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"ప్రస్తుత Android Beam బదిలీలకు సంబంధించిన సమాచారాన్ని స్వీకరించడానికి ఈ అనువర్తనాన్ని అనుమతిస్తుంది"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"పాస్‌వర్డ్ నియమాలను సెట్ చేయండి"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"స్క్రీన్-అన్‌లాక్ పాస్‌వర్డ్‌ల్లో అనుమతించబడే అక్షరాల  సంఖ్యను మరియు అక్షరాలను నియంత్రించండి."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"స్క్రీన్-అన్‌లాక్ ప్రయత్నాలను పర్యవేక్షించండి"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"ఫార్మాట్ చేయి"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB డీబగ్గింగ్ కనెక్ట్ చేయబడింది"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB డీబగ్గింగ్‌ను నిలిపివేయడానికి తాకండి."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"ఇన్‌పుట్ పద్ధతిని ఎంచుకోండి"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"ఇన్‌పుట్ పద్ధతులను సెటప్ చేయి"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"భౌతిక కీబోర్డ్"</string>
     <string name="hardware" msgid="7517821086888990278">"హార్డ్‌వేర్"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"కీబోర్డ్ లేఅవుట్‌ను ఎంచుకోండి"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"ప్రస్తుత వినియోగదారు <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"యజమాని"</string>
     <string name="error_message_title" msgid="4510373083082500195">"లోపం"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"ఈ మార్పును మీ నిర్వాహకుడు అనుమతించలేదు"</string>
     <string name="app_not_found" msgid="3429141853498927379">"ఈ చర్యను నిర్వహించడానికి అనువర్తనం ఏదీ కనుగొనబడలేదు"</string>
     <string name="revoke" msgid="5404479185228271586">"ఉపసంహరించండి"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"అన్‌లాక్ నమూనా"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"పాస్‌వర్డ్"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 11d24df..35f73f4 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"ช่วยให้แอปพลิเคชันสามารถจัดสรรและใช้ใบรับรอง DRM ได้ ไม่จำเป็นสำหรับแอปปกติทั่วไป"</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"รับสถานะการโอน Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"อนุญาตให้แอปพลิเคชันนี้รับข้อมูลเกี่ยวกับการโอน Android Beam ปัจจุบัน"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"ตั้งค่ากฎรหัสผ่าน"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"ควบคุมความยาวและอักขระที่อนุญาตให้ใช้ในรหัสผ่านการปลดล็อกหน้าจอ"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ตรวจสอบความพยายามในการปลดล็อกหน้าจอ"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"รูปแบบ"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"เชื่อมต่อการแก้ไขข้อบกพร่อง USB แล้ว"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"แตะเพื่อปิดใช้งานการแก้ไขข้อบกพร่องของ USB"</string>
-    <string name="select_input_method" msgid="4653387336791222978">"เลือกวิธีการป้อนข้อมูล"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"ตั้งค่าวิธีการป้อนข้อมูล"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"แป้นพิมพ์บนเครื่อง"</string>
     <string name="hardware" msgid="7517821086888990278">"ฮาร์ดแวร์"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"เลือกรูปแบบแป้นพิมพ์"</string>
@@ -1385,11 +1391,11 @@
     <string name="permlab_trust_listener" msgid="1765718054003704476">"ฟังการเปลี่ยนแปลงของสถานะความน่าเชื่อถือ"</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"อนุญาตให้แอปพลิเคชันฟังการเปลี่ยนแปลงที่มีต่อสถานะความน่าเชื่อถือ"</string>
     <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"เสนอตัวแทนที่เชื่อถือได้"</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"ช่วยให้แอปพลิเคชันสามารถเสนอตัวแทนที่เชื่อถือได้"</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"เปิดเมนูการตั้งค่าตัวแทนที่เชื่อถือได้"</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"อนุญาตให้แอปพลิเคชันเปิดกิจกรรมที่เปลี่ยนพฤติกรรมตัวแทนที่เชื่อถือได้"</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"ผูกกับบริการของตัวแทนที่เชื่อถือได้"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"อนุญาตให้แอปพลิเคชันผูกกับบริการของตัวแทนที่เชื่อถือได้"</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"ช่วยให้แอปพลิเคชันสามารถเสนอเอเจนต์ความน่าเชื่อถือให้ได้"</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"เปิดเมนูการตั้งค่าเอเจนต์ความน่าเชื่อถือได้"</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"อนุญาตให้แอปพลิเคชันเปิดกิจกรรมที่เปลี่ยนพฤติกรรมเอเจนต์ความน่าเชื่อถือได้"</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"ผูกกับบริการของเอเจนต์ความน่าเชื่อถือได้"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"อนุญาตให้แอปพลิเคชันผูกกับบริการของเอเจนต์ความน่าเชื่อถือได้"</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"โต้ตอบกับการอัปเดตและระบบการกู้คืน"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"ช่วยให้แอปพลิเคชันสามารถโต้ตอบกับระบบการกู้คืนและการอัปเดตระบบ"</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"สร้างเซสชันการฉายภาพสื่อ"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"ผู้ใช้ปัจจุบัน <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="owner_name" msgid="2716755460376028154">"เจ้าของ"</string>
     <string name="error_message_title" msgid="4510373083082500195">"ข้อผิดพลาด"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"ผู้ดูแลระบบไม่อนุญาตการเปลี่ยนแปลงนี้"</string>
     <string name="app_not_found" msgid="3429141853498927379">"ไม่พบแอปพลิเคชันสำหรับการทำงานนี้"</string>
     <string name="revoke" msgid="5404479185228271586">"เพิกถอน"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"รูปแบบการปลดล็อก"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"รหัสผ่าน"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index bb93e06..c0ea0d9 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Nagbibigay-daan sa isang application na makapagbigay at gumamit ng mga DRM certficate. Hindi dapat kailanman kailanganin para sa mga normal na app."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Tanggapin ang status ng paglilipat ng Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Pinapayagan ang application na ito na tumanggap ng impormasyon tungkol sa mga kasalukuyang paglilipat ng Android Beam"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Magtakda ng mga panuntunan sa password"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolin ang haba at mga character na pinapayagan sa mga password sa pag-unlock ng screen."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Subaybayan ang mga pagsubok sa pag-unlock ng screen"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Konektado ang debugging ng USB"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Pindutin upang huwag paganahin ang pag-debug ng USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Pumili ng pamamaraan ng pag-input"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"I-set up paraan ng pag-input"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Aktwal na keyboard"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Pumili ng layout ng keyboard"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Kasalukuyang user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"May-ari"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Error"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Ang pagbabagong ito ay hindi pinapahintulutan ng iyong administrator"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Walang nakitang application na mangangasiwa sa pagkilos na ito"</string>
     <string name="revoke" msgid="5404479185228271586">"Bawiin"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"pattern sa pag-unlock"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"password"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 373dc93..5b6b004 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Bir uygulamanın DRM sertifikaları için temel hazırlık yapmasına ve bunları kullanmasına izin verir. Normal uygulamalar için hiçbir zaman gerekmez."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android Beam aktarım durumunu al"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Bu uygulamanın mevcut Android Beam aktarımlarıyla ilgili bilgi almasına izin verir"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Şifre kuralları ayarla"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Ekran kilidini açma şifrelerinde izin verilen uzunluğu ve karakterleri denetleme."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Ekran kilidini açma denemelerini izle"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Biçimlendir"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hata ayıklaması bağlandı"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB hata ayıklama özelliğini devre dışı bırakmak için dokunun."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Giriş yöntemini seçin"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Giriş yöntemlerini ayarla"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fiziksel klavye"</string>
     <string name="hardware" msgid="7517821086888990278">"Donanım"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Klavye düzeni seçin"</string>
@@ -1388,8 +1394,8 @@
     <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Bir uygulamanın güven aracısı sağlamasına izin verir."</string>
     <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Güven aracısı ayarlar menüsünü başlat."</string>
     <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Bir uygulamanın, güven aracısı davranışını değiştirecek bir etkinlik başlatmasına izin verir."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Güven aracı hizmetine bağlan"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Bir uygulamanın, güven aracı hizmetine bağlanmasına izin verir."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Güven aracısı hizmetine bağlan"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Bir uygulamanın, güven aracısı hizmetine bağlanmasına izin verir."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Güncelleme ve kurtarma sistemiyle etkileşim kur"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Bir uygulamaya, kurtarma sistemi ve sistem güncellemeriyle etkileşim kurma izni verir."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Medya yansıtma oturumları oluştur"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Geçerli kullanıcı: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Sahibi"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Hata"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Yöneticiniz bu değişikliğe izin vermiyor"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Bu eylemi gerçekleştirecek bir uygulama bulunamadı"</string>
     <string name="revoke" msgid="5404479185228271586">"İptal et"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"kilit açma deseni"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"şifre"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index beeb72b..b279863 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Дозволяє додатку надавати та використовувати сертифікати DRM. Ніколи не застосовується для звичайних додатків."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Отримувати інформацію про стан функції Передавання даних Android."</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Додаток може отримувати інформацію про поточне передавання даних за допомогою функції Передавання даних Android"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Устан. правила пароля"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролювати довжину паролів для розблокування екрана та дозволені в них символи."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Відстежув. спроби розблок. екрана"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Форматув."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Налагодження USB завершено"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Торкніться, щоб вимкнути налагодження USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Вибрати метод введення"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Налаштувати методи введення"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Фізична клавіатура"</string>
     <string name="hardware" msgid="7517821086888990278">"Обладнання"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Виберіть розкладку клавіатури"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Поточний користувач: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Власник"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Помилка"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Ця дія заборонена адміністратором"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Не знайдено програму для обробки цієї дії"</string>
     <string name="revoke" msgid="5404479185228271586">"Анулювати"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN-код"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"ключ розблокування"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"пароль"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index b4f73a1..13e85d2 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"‏ایک ایپ کو  DRM سرٹیفکیٹس فراہم کرنے اور ان کا استعمال کرنے کی اجازت دیتا ہے۔ عام ایپس کیلئے کبھی بھی اس کی ضرورت نہیں ہوتی ہے۔"</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"‏Android Beam منتقلی کی صورت حال موصول کریں"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"‏اس ایپلیکیشن کو Android Beam کی حالیہ منتقلیوں کے بارے میں معلومات موصول کرنے کی اجازت دیتا ہے"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"پاس ورڈ کے اصول سیٹ کریں"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"اسکرین غیر مقفل کرنے کے پاس ورڈز میں مجاز طوالت اور حروف کو کنٹرول کریں۔"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"اسکرین غیر مقفل کرنے کی کوششیں مانیٹر کریں"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"فارمیٹ کریں"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏USB ڈیبگ کرنا مربوط ہو گیا"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"‏USB ڈیبگنگ کو غیر فعال کرنے کیلئے ٹچ کریں۔"</string>
-    <string name="select_input_method" msgid="4653387336791222978">"ان پٹ کا طریقہ منتخب کریں"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"ان پٹ کے طریقوں کو ترتیب دیں"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"طبعی کی بورڈ"</string>
     <string name="hardware" msgid="7517821086888990278">"ہارڈ ویئر"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"کی بورڈ کا خاکہ منتخب کریں"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"موجودہ صارف <xliff:g id="NAME">%1$s</xliff:g>۔"</string>
     <string name="owner_name" msgid="2716755460376028154">"مالک"</string>
     <string name="error_message_title" msgid="4510373083082500195">"خرابی"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"آپ کے منتظم کے ذریعے اس تبدیلی کی اجازت نہیں ہے"</string>
     <string name="app_not_found" msgid="3429141853498927379">"اس عمل کو ہینڈل کرنے کیلئے کوئی ایپلیکیشن نہیں ملا"</string>
     <string name="revoke" msgid="5404479185228271586">"منسوخ کریں"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"غیر مقفل کرنے کا پیٹرن"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"پاس ورڈ"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index cf19c17..22877fb 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Ilova DRM sertifikatlarini sinxronlashi va ulardan foydalanishi mumkin. Ushbu ruxsatnoma faqat maxsus ilovalar uchun talab qilinadi."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Android Beam uzatish holatini olish"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Ushbu ilovaga joriy Android Beam uzatishlari haqida ma\'lumotlarni olish ruxsati berilsin."</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Parol qoidalarini o‘rnatish"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Ekran qulfini ochish parollariga ruxsat berilgan belgilar va ularning uzunligini boshqarish."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Ekranni qulfdan chiqarish urinishlarini nazorat qilish"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB nosozlikni tuzatish ulandi"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB orqali sozlashni o‘chirib qo‘yish uchun bosing."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Matn kiritish usulini tanlang"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Kiritish usullarini sozlash"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Tashqi tugmatag"</string>
     <string name="hardware" msgid="7517821086888990278">"Qurilma"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Tugmalar tartibini tanlash"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Joriy foydalanuvchi <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Egasi"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Xato"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Ushbu o‘zgarishni amalga oshirish uchun administrator ruxsat bermagan"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Ushbu amalni bajaradigan dastur topilmadi"</string>
     <string name="revoke" msgid="5404479185228271586">"Boshlang‘ich holatga tiklash"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN kod"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"qulfdan chiqarish chizmasi"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"parol"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 0006948..da39865 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Cho phép ứng dụng cung cấp và sử dụng chứng chỉ DRM. Không cần thiết cho các ứng dụng thông thường."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Nhận trạng thái chuyển của Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Cho phép ứng dụng này nhận thông tin về các lần chuyển hiện tại của Android Beam"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Đặt quy tắc mật khẩu"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kiểm soát độ dài và ký tự được phép trong mật khẩu mở khóa màn hình."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Giám sát những lần thử mở khóa màn hình"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Định dạng"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Gỡ lỗi USB đã được kết nối"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Chạm để vô hiệu hóa gỡ lỗi USB."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Chọn phương thức nhập"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Thiết lập phương thức nhập"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Bàn phím thực"</string>
     <string name="hardware" msgid="7517821086888990278">"Phần cứng"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Chọn bố cục bàn phím"</string>
@@ -1386,10 +1392,10 @@
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"Cho phép ứng dụng quan sát các thay đổi ở trạng thái đáng tin cậy."</string>
     <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Cung cấp tác nhân đáng tin cậy."</string>
     <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Cho phép ứng dụng cung cấp tác nhân đáng tin cậy."</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Khởi chạy menu cài đặt của đại lý tin cậy."</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Cho phép ứng dụng khởi chạy hoạt động thay đổi hoạt động của đại lý tin cậy."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Liên kết với một dịch vụ của đại lý đáng tin cậy"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Cho phép ứng dụng liên kết với một dịch vụ của đại lý đáng tin cậy."</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Chạy menu cài đặt của tác nhân đáng tin cậy."</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Cho phép ứng dụng khởi chạy hoạt động thay đổi hoạt động của tác nhân đáng tin cậy."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Liên kết với một dịch vụ của tác nhân đáng tin cậy"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Cho phép ứng dụng liên kết với một dịch vụ của tác nhân đáng tin cậy."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Tương tác với hệ thống khôi phục và bản cập nhật"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Cho phép ứng dụng tương tác với hệ thống khôi phục và bản cập nhật hệ thống."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Tạo phiên chiếu phương tiện"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Người dùng hiện tại <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Chủ sở hữu"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Lỗi"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Quản trị viên của bạn không cho phép thực hiện thay đổi này"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Không tìm thấy ứng dụng nào để xử lý tác vụ này"</string>
     <string name="revoke" msgid="5404479185228271586">"Thu hồi"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"Mã PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"hình mở khóa"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"mật khẩu"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 78520d3..afcc0a8 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"允许应用配置和使用DRM证书。普通应用绝不需要此权限。"</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"接收Android Beam的传输状态"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"允许此应用接收Android Beam当前传输内容的相关信息"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"设置密码规则"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"控制屏幕解锁密码所允许的长度和字符。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"监视屏幕解锁尝试次数"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"格式化"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已连接到USB调试"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"触摸可停用USB调试。"</string>
-    <string name="select_input_method" msgid="4653387336791222978">"选择输入法"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"设置输入法"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"物理键盘"</string>
     <string name="hardware" msgid="7517821086888990278">"硬件"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"选择键盘布局"</string>
@@ -1395,7 +1401,7 @@
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"创建媒体投影会话"</string>
     <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"允许应用创建媒体投影会话。这些会话可让应用截取显示内容和音频内容。普通应用绝不需要此权限。"</string>
     <string name="permlab_readInstallSessions" msgid="6165432407628065939">"读取安装会话"</string>
-    <string name="permdesc_readInstallSessions" msgid="2049771699626019849">"允许应用读取安装会话。这样,应用将可以查看有关当前程序包安装的详情。"</string>
+    <string name="permdesc_readInstallSessions" msgid="2049771699626019849">"允许应用读取安装会话。这样,应用将可以查看有关当前软件包安装的详情。"</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"触摸两次可进行缩放控制"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"无法添加小部件。"</string>
     <string name="ime_action_go" msgid="8320845651737369027">"开始"</string>
@@ -1414,8 +1420,8 @@
     <string name="deny" msgid="2081879885755434506">"拒绝"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"权限请求"</string>
     <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"应用对帐户 <xliff:g id="ACCOUNT">%s</xliff:g>\n 提出权限请求。"</string>
-    <string name="forward_intent_to_owner" msgid="570916783072215572">"您目前正在个人空间使用此应用"</string>
-    <string name="forward_intent_to_work" msgid="8624579696577525279">"您目前正在工作空间使用此应用"</string>
+    <string name="forward_intent_to_owner" msgid="570916783072215572">"您目前是在个人空间内使用此应用"</string>
+    <string name="forward_intent_to_work" msgid="8624579696577525279">"您目前是在工作空间内使用此应用"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"输入法"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"同步"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"辅助功能"</string>
@@ -1626,15 +1632,14 @@
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁手机。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"删除"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"要将音量提高到建议的音量以上吗?\n\n长时间聆听高音量内容可能会损伤您的听力。"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"要将音量调高到推荐水平以上吗?\n\n长时间保持高音量可能会损伤听力。"</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"持续按住双指即可启用辅助功能。"</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"辅助功能已启用。"</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"已取消辅助功能。"</string>
     <string name="user_switched" msgid="3768006783166984410">"当前用户是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
     <string name="owner_name" msgid="2716755460376028154">"机主"</string>
     <string name="error_message_title" msgid="4510373083082500195">"错误"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"您的管理员不允许进行此更改"</string>
     <string name="app_not_found" msgid="3429141853498927379">"找不到可处理此操作的应用"</string>
     <string name="revoke" msgid="5404479185228271586">"撤消"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN码"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"解锁图案"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"密码"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index c493759..b145740 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"允許應用程式準備和使用 DRM 憑證,但一般應用程式並不需要使用。"</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"接收 Android Beam 的傳送狀態"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"允許應用程式接收 Android Beam 目前傳送的資料"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"控制螢幕解鎖密碼所允許的長度和字元。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"監控螢幕解鎖嘗試次數"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"格式"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"輕觸即可停用 USB 偵錯。"</string>
-    <string name="select_input_method" msgid="4653387336791222978">"選擇輸入法"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"設定輸入法"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"實體鍵盤"</string>
     <string name="hardware" msgid="7517821086888990278">"硬件"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"選取鍵盤配置"</string>
@@ -1386,10 +1392,10 @@
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"允許應用程式聽取信任狀態的變更。"</string>
     <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"提供信任的代理程式。"</string>
     <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"允許應用程式提供信任的代理程式。"</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"啟動信任代理的程式設定選單。"</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"啟動信任代理程式的設定選單。"</string>
     <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"允許應用程式啟動可變更信任代理程式行為的活動。"</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"繫結至信任的代理程式服務"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"允許應用程式繫結至信任的代理程式服務。"</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"繫結至信任的代理程式"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"允許應用程式繫結至信任的代理程式。"</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"與更新和復原系統互動"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"允許應用程式與復原系統和系統更新互動。"</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"建立媒體投影工作階段"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"目前的用戶是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
     <string name="owner_name" msgid="2716755460376028154">"擁有者"</string>
     <string name="error_message_title" msgid="4510373083082500195">"錯誤"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"您的管理員不允許這項變更"</string>
     <string name="app_not_found" msgid="3429141853498927379">"找不到處理這項操作的應用程式"</string>
     <string name="revoke" msgid="5404479185228271586">"撤銷"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"解鎖圖案"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"密碼"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 41d8f42..5109256 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"允許應用程式佈建及使用 DRM 憑證 (一般應用程式並不需要)。"</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"接收 Android Beam 的傳輸狀態"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"允許應用程式接收 Android Beam 目前傳輸的資訊"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"控制螢幕解鎖密碼所允許的長度和字元。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"監視螢幕解鎖嘗試次數"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"格式化"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"輕觸即可停用 USB 偵錯。"</string>
-    <string name="select_input_method" msgid="4653387336791222978">"選擇輸入法"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"設定輸入法"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"實體鍵盤"</string>
     <string name="hardware" msgid="7517821086888990278">"硬體"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"選取鍵盤配置"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"目前的使用者是 <xliff:g id="NAME">%1$s</xliff:g>。"</string>
     <string name="owner_name" msgid="2716755460376028154">"擁有者"</string>
     <string name="error_message_title" msgid="4510373083082500195">"錯誤"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"您的管理員不允許這項變更"</string>
     <string name="app_not_found" msgid="3429141853498927379">"找不到支援此操作的應用程式"</string>
     <string name="revoke" msgid="5404479185228271586">"撤銷"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"解鎖圖形"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"密碼"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 5861c16..3c09790 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -739,6 +739,10 @@
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Ivumela uhlelo lokusebenza ekunikezweni nokusetshenziswa kwezitifiketi ze-DRM. Akufanele kudingeke kuzinhlelo zokusebenza ezivamile."</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"Thola isimo sokundlulisa se-Android Beam"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Ivumela lolu hlelo lokusebenza ukuthi luthole ulwazi mayelana nokundluliswa kwamanje kwe-Android Beam"</string>
+    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
+    <skip />
+    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Misa imithetho yephasiwedi"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Lawula ubude nezinhlamvu ezivunyelwe kumaphasiwedi okuvula isikrini"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Gaka imizamo yokuvula isikrini"</string>
@@ -1339,8 +1343,10 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Ifomethi"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ukulungisa iphutha le-USB kuxhunyiwe"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Thinta ukwenza ukuthi ukudibhaga kwe-USB kungasebenzi."</string>
-    <string name="select_input_method" msgid="4653387336791222978">"Khetha indlela yokufaka"</string>
-    <string name="configure_input_methods" msgid="9091652157722495116">"Izilungiselelo zezindlela zokufakwayo"</string>
+    <!-- no translation found for select_input_method (8547250819326693584) -->
+    <skip />
+    <!-- no translation found for configure_input_methods (4769971288371946846) -->
+    <skip />
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Ukwakheka kwekhibhodi"</string>
     <string name="hardware" msgid="7517821086888990278">"I-Hardware"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Khetha isendlalelo sekhibhodi"</string>
@@ -1384,12 +1390,12 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Ivumela uhlelo lokusebenza ukuthi lulawule ukhiye wokuqapha."</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"Lalela izinguquko zesimo sokuthemba."</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"Ivumela uhlelo lokusebenza ukuthi lilalelele izinguquko kusimo sethemba."</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Nikeza umsebenzeli owethembekile."</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Ivumela uhlelo lokusebenza ukunikeza umsebenzeli owethembekile."</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Ivula imenyu yezilungiselelo zomsebenzeli."</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Ivumela uhlelo lokusebenza ukuqalisa umsebenzi oshintsha ukuziphatha komsebenzeli owethembekile."</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Bophezela kusevisi yomenzeli wethemba"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Ivumela uhlelo lokusebenza ukuthi libophezeleke kusevisi yomenzeli wethemba."</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Nikeza umsebenzeli wokuthemba."</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Ivumela uhlelo lokusebenza ukunikeza umsebenzeli wokuthemba."</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Ivula imenyu yezilungiselelo zomsebenzeli wokuthemba."</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Ivumela uhlelo lokusebenza ukuqalisa umsebenzi oshintsha ukuziphatha komsebenzeli wokuthemba."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Bophezela kusevisi yomsebenzeli wokuthemba"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Ivumela uhlelo lokusebenza ukuthi libophezeleke kusevisi yomsebenzeli wokuthemba."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Ixhumana nesibuyekezo nesistimu yokutakula"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"Ivumela uhlelo lokusebenza ukuthi lixhumane nesistimu yokutakula nezibuyekezo zesistimu."</string>
     <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Dala isikhathi sephrojekthi semidiya"</string>
@@ -1633,8 +1639,7 @@
     <string name="user_switched" msgid="3768006783166984410">"Umsebenzisi wamanje <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Umnikazi"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Iphutha"</string>
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Le nguquko ayivumelekile ngomqondisi wakho"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Alukho uhlelo lokusebenza olutholakele lokuphatha lesi senzo"</string>
     <string name="revoke" msgid="5404479185228271586">"Chitha"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"I-ISO A0"</string>
@@ -1765,4 +1770,104 @@
     <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"IPHINIKHODI"</string>
     <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"iphethini yokuvula"</string>
     <string name="lock_to_app_unlock_password" msgid="795224196583495868">"iphasiwedi"</string>
+    <!-- no translation found for description_autv_ctc (1340773034128413833) -->
+    <skip />
+    <!-- no translation found for description_autv_g (8825932008126488114) -->
+    <skip />
+    <!-- no translation found for description_autv_pg (3102051294835672333) -->
+    <skip />
+    <!-- no translation found for description_autv_m (1090796276190749241) -->
+    <skip />
+    <!-- no translation found for description_autv_ma15 (970119104753434051) -->
+    <skip />
+    <!-- no translation found for description_autv_r18 (3826039266665650748) -->
+    <skip />
+    <!-- no translation found for description_autv_x18 (2076614946730171971) -->
+    <skip />
+    <!-- no translation found for description_detv_all (4290816084213277907) -->
+    <skip />
+    <!-- no translation found for description_detv_12 (1483291295919180849) -->
+    <skip />
+    <!-- no translation found for description_detv_16 (1530748520169877780) -->
+    <skip />
+    <!-- no translation found for description_detv_18 (6932133267820316706) -->
+    <skip />
+    <!-- no translation found for description_estv_all (4617683093722624240) -->
+    <skip />
+    <!-- no translation found for description_estv_i (1141171160833794692) -->
+    <skip />
+    <!-- no translation found for description_estv_7 (4917355218226086349) -->
+    <skip />
+    <!-- no translation found for description_estv_13 (1591456940863913304) -->
+    <skip />
+    <!-- no translation found for description_estv_18 (1220200554553594583) -->
+    <skip />
+    <!-- no translation found for description_frtv_all (5277155895495938542) -->
+    <skip />
+    <!-- no translation found for description_frtv_10 (4751687393402667290) -->
+    <skip />
+    <!-- no translation found for description_frtv_12 (6813646899508030376) -->
+    <skip />
+    <!-- no translation found for description_frtv_16 (4466993068286008261) -->
+    <skip />
+    <!-- no translation found for description_frtv_18 (6486375640186293566) -->
+    <skip />
+    <!-- no translation found for description_krtv_all (11497981488871053) -->
+    <skip />
+    <!-- no translation found for description_krtv_7 (6204900788594114856) -->
+    <skip />
+    <!-- no translation found for description_krtv_12 (5134514644432355428) -->
+    <skip />
+    <!-- no translation found for description_krtv_15 (1183692678647313272) -->
+    <skip />
+    <!-- no translation found for description_krtv_19 (7021986912313208481) -->
+    <skip />
+    <!-- no translation found for description_nltv_v (3847993626347313388) -->
+    <skip />
+    <!-- no translation found for description_nltv_f (6053045297000290324) -->
+    <skip />
+    <!-- no translation found for description_nltv_s (5727758317180609838) -->
+    <skip />
+    <!-- no translation found for description_nltv_d (8647908408678974106) -->
+    <skip />
+    <!-- no translation found for description_nltv_da (6201574796131887422) -->
+    <skip />
+    <!-- no translation found for description_nltv_l (4895256473269741839) -->
+    <skip />
+    <!-- no translation found for description_nltv_al (438113237508206711) -->
+    <skip />
+    <!-- no translation found for description_nltv_6 (4940119514342845737) -->
+    <skip />
+    <!-- no translation found for description_nltv_9 (7229781600578274275) -->
+    <skip />
+    <!-- no translation found for description_nltv_12 (4096709091642456107) -->
+    <skip />
+    <!-- no translation found for description_nltv_16 (5921176624389788946) -->
+    <skip />
+    <!-- no translation found for description_ustvpg (3666171166900312727) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_d (6552868431924879897) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_l (2427588153488291892) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_s (2556047043212535339) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_v (6647466085048806213) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_fv (4015953953338931020) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y (2271448022073929890) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_y7 (8931861188215869211) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_g (506861774854051282) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_pg (4238749719629801564) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_14 (6305164472373004907) -->
+    <skip />
+    <!-- no translation found for description_ustvpg_ma (5842074394338699982) -->
+    <skip />
+    <!-- no translation found for battery_saver_description (724302068634956656) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index a31f18f..2baa599 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3784,6 +3784,8 @@
         <attr name="elegantTextHeight" format="boolean" />
         <!-- Text letter-spacing. -->
         <attr name="letterSpacing" format="float" />
+        <!-- Font feature settings. -->
+        <attr name="fontFeatureSettings" format="string" />
     </declare-styleable>
     <declare-styleable name="TextClock">
         <!-- Specifies the formatting pattern used to show the time and/or date
@@ -4079,6 +4081,8 @@
         <attr name="elegantTextHeight" />
         <!-- Text letter-spacing. -->
         <attr name="letterSpacing" />
+        <!-- Font feature settings. -->
+        <attr name="fontFeatureSettings" />
     </declare-styleable>
     <declare-styleable name="TextViewAppearance">
         <!-- Base text color, typeface, size, and style. -->
diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml
index 6988881..ccbb8bc 100644
--- a/core/res/res/values/colors_material.xml
+++ b/core/res/res/values/colors_material.xml
@@ -89,8 +89,8 @@
     <color name="material_teal_A200">#ff18ffff</color>
     <color name="material_teal_A400">#ff00e5ff</color>
 
-    <!-- Accent color used by Settings -->
-    <color name="material_dark_teal_A400">#ff009688</color>
+    <color name="material_deep_teal_A200">#ff80cbc4</color>
+    <color name="material_deep_teal_A500">#ff009688</color>
 
     <color name="material_green_100">#ffb7e1cd</color>
     <color name="material_green_300">#ff57bb8a</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 217658c..b9e5c66 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1661,4 +1661,8 @@
     <!--Support decoding the user data payload as pack GSM 8-bit (a GSM alphabet
         string that's stored in 8-bit unpacked format) characters.-->
     <bool translatable="false" name="config_sms_decode_gsm_8bit_data">false</bool>
+
+    <!-- Package name providing WebView implementation. -->
+    <string name="config_webViewPackageName" translatable="false">com.android.webview</string>
+
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 195851f..4761f1a 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1974,6 +1974,13 @@
     <string name="permdesc_bluetoothPriv" product="default">Allows the app to
       pair with remote devices without user interaction.</string>
 
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_bluetoothMap">access Bluetooth MAP data</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_bluetoothMap" product="tablet">Allows the app to access Bluetooth MAP data.</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_bluetoothMap" product="default">Allows the app to access Bluetooth MAP data.</string>
+
     <string name="permlab_accessWimaxState">connect and disconnect from WiMAX</string>
     <string name="permdesc_accessWimaxState">Allows the app to determine whether
      WiMAX is enabled and information about any WiMAX networks that are
@@ -2167,6 +2174,11 @@
     <string name="permlab_handoverStatus">Receive Android Beam transfer status</string>
     <string name="permdesc_handoverStatus">Allows this application to receive information about current Android Beam transfers</string>
 
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_removeDrmCertificates">remove DRM certificates</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_removeDrmCertificates">Allows an application to remove DRM certficates. Should never be needed for normal apps.</string>
+
     <!-- Policy administration -->
 
     <!-- Title of policy access to limiting the user's password choices -->
@@ -4841,10 +4853,186 @@
     <!-- Lock-to-app unlock password string -->
     <string name="lock_to_app_unlock_password">password</string>
 
+    <!-- TV content rating system strings for AM TV -->
+
+    <!-- TV content rating system strings for AR TV -->
+
+    <!-- TV content rating system strings for AU TV -->
+    <string name="display_name_autv" translatable="false">Australian TV Classification</string>
+    <string name="display_name_autv_ctc" translatable="false">CTC</string>
+    <string name="display_name_autv_g" translatable="false">G</string>
+    <string name="display_name_autv_pg" translatable="false">PG</string>
+    <string name="display_name_autv_m" translatable="false">M</string>
+    <string name="display_name_autv_ma15" translatable="false">MA 15+</string>
+    <string name="display_name_autv_r18" translatable="false">R 18+</string>
+    <string name="display_name_autv_x18" translatable="false">X 18+</string>
+    <string name="description_autv_ctc">This has advertising approval, but is not yet classified.</string>
+    <string name="description_autv_g">The content is very mild in impact, and suitable for everyone.</string>
+    <string name="description_autv_pg">The content is mild in impact, but it may contain content that children find confusing or upsetting and may require the guidance or parents and guardians.</string>
+    <string name="description_autv_m">The content is moderate in impact, and it is recommended for teenagers aged 15 years and over.</string>
+    <string name="description_autv_ma15">The content is strong in impact, and it is legally restricted to persons 15 years and over.</string>
+    <string name="description_autv_r18">The content is high in impact, and it is restricted to adults.</string>
+    <string name="description_autv_x18">The content is restricted to adults. This classification is a special and legally restricted category which contains only sexually explicit content.</string>
+
+    <!-- TV content rating system strings for BG TV -->
+
+    <!-- TV content rating system strings for BR TV -->
+    <string name="display_name_brtv" translatable="false">Brazil Content Rating</string>
+    <string name="display_name_brtv_l" translatable="false">Livre</string>
+    <string name="display_name_brtv_10" translatable="false">10 anos</string>
+    <string name="display_name_brtv_12" translatable="false">12 anos</string>
+    <string name="display_name_brtv_14" translatable="false">14 anos</string>
+    <string name="display_name_brtv_16" translatable="false">16 anos</string>
+    <string name="display_name_brtv_18" translatable="false">18 anos</string>
+    <string name="description_brtv_l" translatable="false">Livre para todos os públicos</string>
+    <string name="description_brtv_10" translatable="false">Não recomendado para menores de 10 anos</string>
+    <string name="description_brtv_12" translatable="false">Não recomendado para menores de 10 anos</string>
+    <string name="description_brtv_14" translatable="false">Não recomendado para menores de 14 anos</string>
+    <string name="description_brtv_16" translatable="false">Não recomendado para menores de 16 anos</string>
+    <string name="description_brtv_18" translatable="false">Não recomendado para menores de 18 anos</string>
+
+    <!-- TV content rating system strings for CA TV -->
+
+    <!-- TV content rating system strings for CH TV -->
+
+    <!-- TV content rating system strings for CL TV -->
+
+    <!-- TV content rating system strings for CO TV -->
+
+    <!-- TV content rating system strings for DE TV -->
+    <string name="display_name_detv" translatable="false">DE-TV</string>
+    <string name="display_name_detv_all" translatable="false">ab 0 Jahren</string>
+    <string name="display_name_detv_12" translatable="false">ab 12 Jahren</string>
+    <string name="display_name_detv_16" translatable="false">ab 16 Jahren</string>
+    <string name="display_name_detv_18" translatable="false">ab 18 Jahren</string>
+    <string name="description_detv_all">Die nachfolgende Sendung ist für alle alters geeignet.</string>
+    <string name="description_detv_12">Die nachfolgende Sendung ist für Zuschauer unter 12 Jahren nicht geeignet.</string>
+    <string name="description_detv_16">Die nachfolgende Sendung ist für Zuschauer unter 16 Jahren nicht geeignet.</string>
+    <string name="description_detv_18">Die nachfolgende Sendung ist für Zuschauer unter 18 Jahren nicht geeignet.</string>
+
+    <!-- TV content rating system strings for DK TV -->
+
+    <!-- TV content rating system strings for ES TV -->
+    <string name="display_name_estv" translatable="false">ES-TV</string>
+    <string name="display_name_estv_all" translatable="false">TP</string>
+    <string name="display_name_estv_i" translatable="false">i</string>
+    <string name="display_name_estv_7" translatable="false">+7</string>
+    <string name="display_name_estv_13" translatable="false">+13</string>
+    <string name="display_name_estv_18" translatable="false">+18</string>
+    <string name="description_estv_all">Programas para todos los públicos</string>
+    <string name="description_estv_i">Programas especialmente recomendados para la infancia</string>
+    <string name="description_estv_7">Programas no recomendados para menores de 7 años (NR7)</string>
+    <string name="description_estv_13">Programas no recomendados para menores de 13 años (NR13)</string>
+    <string name="description_estv_18">Programas no recomendados para menores de 18 años (NR18)</string>
+
+    <!-- TV content rating system strings for FI TV -->
+
+    <!-- TV content rating system strings for FR TV -->
+    <string name="display_name_frtv" translatable="false">FR-TV</string>
+    <string name="display_name_frtv_all" translatable="false">Les programmes tous publics</string>
+    <string name="display_name_frtv_10" translatable="false">Déconseillé aux -10 ans</string>
+    <string name="display_name_frtv_12" translatable="false">Déconseillé aux -12 ans</string>
+    <string name="display_name_frtv_16" translatable="false">Déconseillé aux -16 ans</string>
+    <string name="display_name_frtv_18" translatable="false">Déconseillé aux -18 ans</string>
+    <string name="description_frtv_all">Les programmes tous publics</string>
+    <string name="description_frtv_10">Programmes comportant certaines scènes susceptibles de heurter les -10 ans.</string>
+    <string name="description_frtv_12">Programmes pouvant troubler les -12 ans, notamment lorsque le scénario recourt de façon systématique et répétée à la violence physique ou psychologique.</string>
+    <string name="description_frtv_16">Programmes à caractère érotique ou de grande violence, susceptibles de nuire à l’épanouissement physique, mental ou moral des -16 ans.</string>
+    <string name="description_frtv_18">Programmes pornographiques ou de très grande violence, réservés à un public adulte averti et susceptibles de nuire à l’épanouissement physique, mental ou moral des -18 ans.</string>
+
+    <!-- TV content rating system strings for GR TV -->
+
+    <!-- TV content rating system strings for HK TV -->
+
+    <!-- TV content rating system strings for HU TV -->
+
+    <!-- TV content rating system strings for ID TV -->
+
+    <!-- TV content rating system strings for IE TV -->
+
+    <!-- TV content rating system strings for IL TV -->
+
+    <!-- TV content rating system strings for IN TV -->
+
+    <!-- TV content rating system strings for IS TV -->
+
+    <!-- TV content rating system strings for KH TV -->
+
+    <!-- TV content rating system strings for KR TV -->
+    <string name="display_name_krtv" translatable="false">KR-TV</string>
+    <string name="display_name_krtv_all" translatable="false">모든연령시청가</string>
+    <string name="display_name_krtv_7" translatable="false">7세이상시청가</string>
+    <string name="display_name_krtv_12" translatable="false">12세이상시청가</string>
+    <string name="display_name_krtv_15" translatable="false">15세이상시청가</string>
+    <string name="display_name_krtv_19" translatable="false">19세이상시청가</string>
+    <string name="description_krtv_all">모든 연령의 시청자가 시청하기에 부적절한 내용이 없는 등급을 말한다.</string>
+    <string name="description_krtv_7">7세미만의 어린이가 시청하기에 부적절한 내용이 포함되어 있어 보호자의 시청지도가 필요한 등급을 말한다.</string>
+    <string name="description_krtv_12">12세미만의 청소년이 시청하기에 부적절한 내용이 포함되어 있어 보호자의 시청지도가 필요한 등급을 말한다.</string>
+    <string name="description_krtv_15">15세미만의 청소년이 시청하기에 부적절한 내용이 포함되어 있어 보호자의 시청지도가 필요한 등급을 말한다.</string>
+    <string name="description_krtv_19">19세미만의 청소년이 시청하기에 부적절한 내용이 포함되어 있어 청소년이 시청할 수 없는 등급을 말한다.</string>
+
+    <!-- TV content rating system strings for MV TV -->
+
+    <!-- TV content rating system strings for MX TV -->
+
+    <!-- TV content rating system strings for MY TV -->
+
+    <!-- TV content rating system strings for NL TV -->
+    <string name="display_name_nltv" translatable="false">NL-TV</string>
+    <string name="display_name_nltv_v" translatable="false">Geweld</string>
+    <string name="display_name_nltv_f" translatable="false">Angst</string>
+    <string name="display_name_nltv_s" translatable="false">Seks</string>
+    <string name="display_name_nltv_d" translatable="false">Discriminatie</string>
+    <string name="display_name_nltv_da" translatable="false">Drugs- en/of alcoholmisbruik</string>
+    <string name="display_name_nltv_l" translatable="false">Grof taalgebruik</string>
+    <string name="display_name_nltv_al" translatable="false">Alle leeftijden</string>
+    <string name="display_name_nltv_6" translatable="false">Let op met kinderen tot 6 jaar</string>
+    <string name="display_name_nltv_9" translatable="false">Let op met kinderen tot 9 jaar</string>
+    <string name="display_name_nltv_12" translatable="false">Let op met kinderen tot 12 jaar</string>
+    <string name="display_name_nltv_16" translatable="false">Let op met kinderen tot 16 jaar</string>
+    <string name="description_nltv_v">Geweld</string>
+    <string name="description_nltv_f">Angst</string>
+    <string name="description_nltv_s">Seks</string>
+    <string name="description_nltv_d">Discriminatie</string>
+    <string name="description_nltv_da">Drugs- en/of alcoholmisbruik</string>
+    <string name="description_nltv_l">Grof taalgebruik</string>
+    <string name="description_nltv_al">De leeftijdscategorie Alle Leeftijden geeft aan dat een mediaproductie geen schadelijke elementen bevat.</string>
+    <string name="description_nltv_6">Mogelijk schadelijk voor kinderen onder de 6 jaar.</string>
+    <string name="description_nltv_9">Mogelijk schadelijk voor kinderen onder de 9 jaar.</string>
+    <string name="description_nltv_12">Mogelijk schadelijk voor kinderen onder de 12 jaar.</string>
+    <string name="description_nltv_16">Mogelijk schadelijk voor kinderen onder de 16 jaar.</string>
+
+    <!-- TV content rating system strings for NZ TV -->
+
+    <!-- TV content rating system strings for PE TV -->
+
+    <!-- TV content rating system strings for PH TV -->
+
+    <!-- TV content rating system strings for PL TV -->
+
+    <!-- TV content rating system strings for PT TV -->
+
+    <!-- TV content rating system strings for RO TV -->
+
+    <!-- TV content rating system strings for RU TV -->
+
+    <!-- TV content rating system strings for RS TV -->
+
+    <!-- TV content rating system strings for SG TV -->
+
+    <!-- TV content rating system strings for SI TV -->
+
+    <!-- TV content rating system strings for TH TV -->
+
+    <!-- TV content rating system strings for TR TV -->
+
+    <!-- TV content rating system strings for TW TV -->
+
+    <!-- TV content rating system strings for UA TV -->
+
+    <!-- TV content rating system strings for US TV -->
     <string name="display_name_ustvpg" translatable="false">US-TV</string>
     <string name="description_ustvpg">The TV Parental Guidelines</string>
-    <string name="display_name_krtv" translatable="false">KR-TV</string>
-
     <string name="display_name_ustvpg_d" translatable="false">D</string>
     <string name="display_name_ustvpg_l" translatable="false">L</string>
     <string name="display_name_ustvpg_s" translatable="false">S</string>
@@ -4856,12 +5044,6 @@
     <string name="display_name_ustvpg_pg" translatable="false">TV-PG</string>
     <string name="display_name_ustvpg_14" translatable="false">TV-14</string>
     <string name="display_name_ustvpg_ma" translatable="false">TV-MA</string>
-    <string name="display_name_krtv_all" translatable="false">모든연령시청가</string>
-    <string name="display_name_krtv_7" translatable="false">7세이상시청가</string>
-    <string name="display_name_krtv_12" translatable="false">12세이상시청가</string>
-    <string name="display_name_krtv_15" translatable="false">15세이상시청가</string>
-    <string name="display_name_krtv_19" translatable="false">19세이상시청가</string>
-
     <string name="description_ustvpg_d">Suggestive dialogue (Usually means talks about sex)</string>
     <string name="description_ustvpg_l">Coarse language</string>
     <string name="description_ustvpg_s">Sexual content</string>
@@ -4873,9 +5055,11 @@
     <string name="description_ustvpg_pg">This program contains material that parents may find unsuitable for younger children.</string>
     <string name="description_ustvpg_14">This program contains some material that many parents would find unsuitable for children under 14 years of age.</string>
     <string name="description_ustvpg_ma">This program is specifically designed to be viewed by adults and therefore may be unsuitable for children under 17.</string>
-    <string name="description_krtv_all">모든 연령의 시청자가 시청하기에 부적절한 내용이 없는 등급을 말한다.</string>
-    <string name="description_krtv_7">7세미만의 어린이가 시청하기에 부적절한 내용이 포함되어 있어 보호자의 시청지도가 필요한 등급을 말한다.</string>
-    <string name="description_krtv_12">12세미만의 청소년이 시청하기에 부적절한 내용이 포함되어 있어 보호자의 시청지도가 필요한 등급을 말한다.</string>
-    <string name="description_krtv_15">15세미만의 청소년이 시청하기에 부적절한 내용이 포함되어 있어 보호자의 시청지도가 필요한 등급을 말한다.</string>
-    <string name="description_krtv_19">19세미만의 청소년이 시청하기에 부적절한 내용이 포함되어 있어 청소년이 시청할 수 없는 등급을 말한다.</string>
+
+    <!-- TV content rating system strings for VE TV -->
+
+    <!-- TV content rating system strings for ZA TV -->
+
+    <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description -->
+    <string name="battery_saver_description">To help improve battery life, battery saver will reduce your device’s performance and restrict 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>
 </resources>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 9ee377f..2dc0438 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -652,7 +652,7 @@
 
     <style name="Widget.Material.ProgressBar.Horizontal" parent="Widget.ProgressBar.Horizontal">
         <item name="progressDrawable">@drawable/progress_horizontal_material</item>
-        <item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal_holo</item>
+        <item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal_material</item>
         <item name="minHeight">16dip</item>
         <item name="maxHeight">16dip</item>
     </style>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index d37e468..84bc62c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1195,6 +1195,7 @@
   <java-symbol type="layout" name="icon_menu_layout" />
   <java-symbol type="layout" name="input_method" />
   <java-symbol type="layout" name="input_method_extract_view" />
+  <java-symbol type="layout" name="input_method_switch_item" />
   <java-symbol type="layout" name="input_method_switch_dialog_title" />
   <java-symbol type="layout" name="js_prompt" />
   <java-symbol type="layout" name="list_content_simple" />
@@ -1839,6 +1840,7 @@
   <java-symbol type="attr" name="actionModeWebSearchDrawable" />
   <java-symbol type="string" name="websearch" />
   <java-symbol type="drawable" name="ic_media_video_poster" />
+  <java-symbol type="string" name="config_webViewPackageName" />
 
   <!-- From SubtitleView -->
   <java-symbol type="dimen" name="subtitle_corner_radius" />
@@ -1893,6 +1895,7 @@
   <java-symbol type="string" name="timepicker_numbers_radius_multiplier_normal" />
   <java-symbol type="string" name="timepicker_transition_mid_radius_multiplier" />
   <java-symbol type="string" name="timepicker_transition_end_radius_multiplier" />
+  <java-symbol type="string" name="battery_saver_description" />
 
   <java-symbol type="string" name="item_is_selected" />
   <java-symbol type="string" name="day_of_week_label_typeface" />
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 42ebb82..e7001c3 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -372,7 +372,7 @@
         <!-- Color palette -->
         <item name="colorPrimaryDark">@color/material_blue_grey_900</item>
         <item name="colorPrimary">@color/material_blue_grey_800</item>
-        <item name="colorAccent">@color/material_light_blue_A200</item>
+        <item name="colorAccent">@color/material_deep_teal_A200</item>
 
         <item name="colorControlNormal">?attr/textColorSecondary</item>
         <item name="colorControlActivated">?attr/colorAccent</item>
@@ -712,9 +712,9 @@
         <item name="fastScrollOverlayPosition">atThumb</item>
 
         <!-- Color palette -->
-        <item name="colorPrimaryDark">@color/material_blue_grey_600</item>
-        <item name="colorPrimary">@color/material_blue_grey_400</item>
-        <item name="colorAccent">@color/material_light_blue_A200</item>
+        <item name="colorPrimaryDark">@color/material_blue_grey_100</item>
+        <item name="colorPrimary">@color/material_blue_grey_50</item>
+        <item name="colorAccent">@color/material_deep_teal_A500</item>
 
         <item name="colorControlNormal">?attr/textColorSecondary</item>
         <item name="colorControlActivated">?attr/colorAccent</item>
@@ -1229,7 +1229,7 @@
     <style name="Theme.Material.Settings" parent="@style/Theme.Material.Light.DarkActionBar">
         <item name="colorPrimary">@color/material_blue_grey_900</item>
         <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
-        <item name="colorAccent">@color/material_dark_teal_A400</item>
+        <item name="colorAccent">@color/material_deep_teal_A500</item>
     </style>
 
 </resources>
diff --git a/core/res/res/xml/tv_content_rating_systems.xml b/core/res/res/xml/tv_content_rating_systems.xml
index 238ce13..7679866 100644
--- a/core/res/res/xml/tv_content_rating_systems.xml
+++ b/core/res/res/xml/tv_content_rating_systems.xml
@@ -17,6 +17,375 @@
 */
 -->
 <rating-system-definitions>
+    <!-- TV content rating system for AM TV -->
+
+    <!-- TV content rating system for AR TV -->
+
+    <!-- TV content rating system for AU TV -->
+    <rating-system-definition id="AU_TV"
+        displayName="@string/display_name_autv"
+        country="AU">
+        <rating-definition id="AU_TV_CTC"
+            displayName="@string/display_name_autv_ctc"
+            description="@string/description_autv_ctc"
+            ageHint="0" />
+        <rating-definition id="AU_TV_G"
+            displayName="@string/display_name_autv_g"
+            description="@string/description_autv_g"
+            ageHint="0" />
+        <rating-definition id="AU_TV_PG"
+            displayName="@string/display_name_autv_pg"
+            description="@string/description_autv_g"
+            ageHint="15" />
+        <rating-definition id="AU_TV_M"
+            displayName="@string/display_name_autv_m"
+            description="@string/description_autv_m"
+            ageHint="15" />
+        <rating-definition id="AU_TV_MA15"
+            displayName="@string/display_name_autv_ma15"
+            description="@string/description_autv_ma15"
+            ageHint="15" />
+        <rating-definition id="AU_TV_R18"
+            displayName="@string/display_name_autv_r18"
+            description="@string/description_autv_r18"
+            ageHint="18" />
+        <rating-definition id="AU_TV_X18"
+            displayName="@string/display_name_autv_x18"
+            description="@string/description_autv_x18"
+            ageHint="18" />
+        <order>
+            <rating id="AU_TV_G" />
+            <rating id="AU_TV_PG" />
+            <rating id="AU_TV_M" />
+            <rating id="AU_TV_MA15" />
+            <rating id="AU_TV_R18" />
+            <rating id="AU_TV_X18" />
+        </order>
+    </rating-system-definition>
+
+    <!-- TV content rating system for BG TV -->
+
+    <!-- TV content rating system for BR TV -->
+    <rating-system-definition id="BR_TV"
+        displayName="@string/display_name_brtv"
+        country="BR">
+        <rating-definition id="BR_TV_L"
+            displayName="@string/display_name_brtv_l"
+            description="@string/description_brtv_l"
+            ageHint="0" />
+        <rating-definition id="BR_TV_10"
+            displayName="@string/display_name_brtv_10"
+            description="@string/description_brtv_10"
+            ageHint="10" />
+        <rating-definition id="BR_TV_12"
+            displayName="@string/display_name_brtv_12"
+            description="@string/description_brtv_12"
+            ageHint="12" />
+        <rating-definition id="BR_TV_14"
+            displayName="@string/display_name_brtv_14"
+            description="@string/description_brtv_14"
+            ageHint="14" />
+        <rating-definition id="BR_TV_16"
+            displayName="@string/display_name_brtv_16"
+            description="@string/description_brtv_16"
+            ageHint="16" />
+        <rating-definition id="BR_TV_18"
+            displayName="@string/display_name_brtv_18"
+            description="@string/description_brtv_18"
+            ageHint="18" />
+        <order>
+            <rating id="BR_TV_L" />
+            <rating id="BR_TV_10" />
+            <rating id="BR_TV_12" />
+            <rating id="BR_TV_14" />
+            <rating id="BR_TV_16" />
+            <rating id="BR_TV_18" />
+        </order>
+    </rating-system-definition>
+
+    <!-- TV content rating system for CA TV -->
+
+    <!-- TV content rating system for CH TV -->
+
+    <!-- TV content rating system for CL TV -->
+
+    <!-- TV content rating system for CO TV -->
+
+    <!-- TV content rating system for DE TV -->
+    <rating-system-definition id="DE_TV"
+        displayName="@string/display_name_detv"
+        country="DE">
+        <rating-definition id="DE_TV_ALL"
+            displayName="@string/display_name_detv_all"
+            description="@string/description_detv_all"
+            ageHint="0" />
+        <rating-definition id="DE_TV_12"
+            displayName="@string/display_name_detv_12"
+            description="@string/description_detv_12"
+            ageHint="12" />
+        <rating-definition id="DE_TV_16"
+            displayName="@string/display_name_detv_16"
+            description="@string/description_detv_16"
+            ageHint="16" />
+        <rating-definition id="DE_TV_18"
+            displayName="@string/display_name_detv_18"
+            description="@string/description_detv_18"
+            ageHint="18" />
+        <order>
+            <rating id="DE_TV_ALL" />
+            <rating id="DE_TV_12" />
+            <rating id="DE_TV_16" />
+            <rating id="DE_TV_18" />
+        </order>
+    </rating-system-definition>
+
+    <!-- TV content rating system for DK TV -->
+
+    <!-- TV content rating system for ES TV -->
+    <rating-system-definition id="ES_TV"
+        displayName="@string/display_name_estv"
+        country="ES">
+        <rating-definition id="ES_TV_ALL"
+            displayName="@string/display_name_estv_all"
+            description="@string/description_estv_all"
+            ageHint="0" />
+        <rating-definition id="ES_TV_I"
+            displayName="@string/display_name_estv_i"
+            description="@string/description_estv_i"
+            ageHint="0" />
+        <rating-definition id="ES_TV_7"
+            displayName="@string/display_name_estv_7"
+            description="@string/description_estv_7"
+            ageHint="7" />
+        <rating-definition id="ES_TV_13"
+            displayName="@string/display_name_estv_13"
+            description="@string/description_estv_13"
+            ageHint="13" />
+        <rating-definition id="ES_TV_18"
+            displayName="@string/display_name_estv_18"
+            description="@string/description_estv_18"
+            ageHint="18" />
+        <order>
+            <rating id="ES_TV_ALL" />
+            <rating id="ES_TV_7" />
+            <rating id="ES_TV_13" />
+            <rating id="ES_TV_18" />
+        </order>
+    </rating-system-definition>
+
+    <!-- TV content rating system for FI TV -->
+
+    <!-- TV content rating system for FR TV -->
+    <rating-system-definition id="FR_TV"
+        displayName="@string/display_name_frtv"
+        country="FR">
+        <rating-definition id="FR_TV_ALL"
+            displayName="@string/display_name_frtv_all"
+            description="@string/description_frtv_all"
+            ageHint="0" />
+        <rating-definition id="FR_TV_10"
+            displayName="@string/display_name_frtv_10"
+            description="@string/description_frtv_10"
+            ageHint="10">
+        </rating-definition>
+        <rating-definition id="FR_TV_12"
+            displayName="@string/display_name_frtv_12"
+            description="@string/description_frtv_12"
+            ageHint="12">
+        </rating-definition>
+        <rating-definition id="FR_TV_16"
+            displayName="@string/display_name_frtv_16"
+            description="@string/description_frtv_16"
+            ageHint="16">
+        </rating-definition>
+        <rating-definition id="FR_TV_18"
+            displayName="@string/display_name_frtv_18"
+            description="@string/description_frtv_18"
+            ageHint="18">
+        </rating-definition>
+        <order>
+            <rating id="FR_TV_ALL" />
+            <rating id="FR_TV_10" />
+            <rating id="FR_TV_12" />
+            <rating id="FR_TV_16" />
+            <rating id="FR_TV_18" />
+        </order>
+    </rating-system-definition>
+
+    <!-- TV content rating system for GR TV -->
+
+    <!-- TV content rating system for HK TV -->
+
+    <!-- TV content rating system for HU TV -->
+
+    <!-- TV content rating system for ID TV -->
+
+    <!-- TV content rating system for IE TV -->
+
+    <!-- TV content rating system for IL TV -->
+
+    <!-- TV content rating system for IN TV -->
+
+    <!-- TV content rating system for IS TV -->
+
+    <!-- TV content rating system for KH TV -->
+
+    <!-- TV content rating system for KR TV -->
+    <rating-system-definition id="KR_TV"
+        displayName="@string/display_name_krtv"
+        country="KR">
+        <rating-definition id="KR_TV_ALL"
+            displayName="@string/display_name_krtv_all"
+            description="@string/description_krtv_all"
+            ageHint="0" />
+        <rating-definition id="KR_TV_7"
+            displayName="@string/display_name_krtv_7"
+            description="@string/description_krtv_7"
+            ageHint="7" />
+        <rating-definition id="KR_TV_12"
+            displayName="@string/display_name_krtv_12"
+            description="@string/description_krtv_12"
+            ageHint="12" />
+        <rating-definition id="KR_TV_15"
+            displayName="@string/display_name_krtv_15"
+            description="@string/description_krtv_15"
+            ageHint="15" />
+        <rating-definition id="KR_TV_19"
+            displayName="@string/display_name_krtv_19"
+            description="@string/description_krtv_19"
+            ageHint="19" />
+        <order>
+            <rating id="KR_TV_ALL" />
+            <rating id="KR_TV_7" />
+            <rating id="KR_TV_12" />
+            <rating id="KR_TV_15" />
+            <rating id="KR_TV_19" />
+        </order>
+    </rating-system-definition>
+
+    <!-- TV content rating system for MV TV -->
+
+    <!-- TV content rating system for MX TV -->
+
+    <!-- TV content rating system for MY TV -->
+
+    <!-- TV content rating system for NL TV -->
+    <rating-system-definition id="NL_TV"
+        displayName="@string/display_name_nltv"
+        country="NL">
+        <sub-rating-definition id="NL_TV_V"
+            displayName="@string/display_name_nltv_v"
+            description="@string/description_nltv_v" />
+        <sub-rating-definition id="NL_TV_F"
+            displayName="@string/display_name_nltv_f"
+            description="@string/description_nltv_f" />
+        <sub-rating-definition id="NL_TV_S"
+            displayName="@string/display_name_nltv_s"
+            description="@string/description_nltv_s" />
+        <sub-rating-definition id="NL_TV_D"
+            displayName="@string/display_name_nltv_d"
+            description="@string/description_nltv_d" />
+        <sub-rating-definition id="NL_TV_DA"
+            displayName="@string/display_name_nltv_da"
+            description="@string/description_nltv_da" />
+        <sub-rating-definition id="NL_TV_L"
+            displayName="@string/display_name_nltv_l"
+            description="@string/description_nltv_l" />
+
+        <rating-definition id="NL_TV_AL"
+            displayName="@string/display_name_nltv_al"
+            description="@string/description_nltv_al"
+            ageHint="0">
+            <sub-rating id="NL_TV_V" />
+            <sub-rating id="NL_TV_F" />
+            <sub-rating id="NL_TV_S" />
+            <sub-rating id="NL_TV_D" />
+            <sub-rating id="NL_TV_DA" />
+            <sub-rating id="NL_TV_L" />
+        </rating-definition>
+        <rating-definition id="NL_TV_6"
+            displayName="@string/display_name_nltv_6"
+            description="@string/description_nltv_6"
+            ageHint="6">
+            <sub-rating id="NL_TV_V" />
+            <sub-rating id="NL_TV_F" />
+            <sub-rating id="NL_TV_S" />
+            <sub-rating id="NL_TV_D" />
+            <sub-rating id="NL_TV_DA" />
+            <sub-rating id="NL_TV_L" />
+        </rating-definition>
+        <rating-definition id="NL_TV_9"
+            displayName="@string/display_name_nltv_9"
+            description="@string/description_nltv_9"
+            ageHint="9">
+            <sub-rating id="NL_TV_V" />
+            <sub-rating id="NL_TV_F" />
+            <sub-rating id="NL_TV_S" />
+            <sub-rating id="NL_TV_D" />
+            <sub-rating id="NL_TV_DA" />
+            <sub-rating id="NL_TV_L" />
+        </rating-definition>
+        <rating-definition id="NL_TV_12"
+            displayName="@string/display_name_nltv_12"
+            description="@string/description_nltv_12"
+            ageHint="12">
+            <sub-rating id="NL_TV_V" />
+            <sub-rating id="NL_TV_F" />
+            <sub-rating id="NL_TV_S" />
+            <sub-rating id="NL_TV_D" />
+            <sub-rating id="NL_TV_DA" />
+            <sub-rating id="NL_TV_L" />
+        </rating-definition>
+        <rating-definition id="NL_TV_16"
+            displayName="@string/display_name_nltv_16"
+            description="@string/description_nltv_16"
+            ageHint="16">
+            <sub-rating id="NL_TV_V" />
+            <sub-rating id="NL_TV_F" />
+            <sub-rating id="NL_TV_S" />
+            <sub-rating id="NL_TV_D" />
+            <sub-rating id="NL_TV_DA" />
+            <sub-rating id="NL_TV_L" />
+        </rating-definition>
+
+        <order>
+            <rating id="NL_TV_AL" />
+            <rating id="NL_TV_6" />
+            <rating id="NL_TV_9" />
+            <rating id="NL_TV_12" />
+            <rating id="NL_TV_16" />
+        </order>
+    </rating-system-definition>
+
+    <!-- TV content rating system for NZ TV -->
+
+    <!-- TV content rating system for PE TV -->
+
+    <!-- TV content rating system for PH TV -->
+
+    <!-- TV content rating system for PL TV -->
+
+    <!-- TV content rating system for PT TV -->
+
+    <!-- TV content rating system for RO TV -->
+
+    <!-- TV content rating system for RU TV -->
+
+    <!-- TV content rating system for RS TV -->
+
+    <!-- TV content rating system for SG TV -->
+
+    <!-- TV content rating system for SI TV -->
+
+    <!-- TV content rating system for TH TV -->
+
+    <!-- TV content rating system for TR TV -->
+
+    <!-- TV content rating system for TW TV -->
+
+    <!-- TV content rating system for UA TV -->
+
+    <!-- TV content rating system for US TV -->
     <rating-system-definition id="US_TVPG"
         displayName="@string/display_name_ustvpg"
         description="@string/description_ustvpg"
@@ -78,8 +447,8 @@
             <sub-rating id="US_TVPG_V" />
         </rating-definition>
         <order>
-            <rating id="US_TVPG_Y" />
-            <rating id="US_TVPG_Y7" />
+            <rating id="US_TVPG_TV_Y" />
+            <rating id="US_TVPG_TV_Y7" />
         </order>
         <order>
             <rating id="US_TVPG_TV_G" />
@@ -89,39 +458,7 @@
         </order>
     </rating-system-definition>
 
-    <rating-system-definition id="KR_TV"
-        displayName="@string/display_name_krtv"
-        country="KR">
-        <rating-definition id="KR_TV_ALL"
-            displayName="@string/display_name_krtv_all"
-            description="@string/description_krtv_all"
-            ageHint="0" />
-        <rating-definition id="KR_TV_7"
-            displayName="@string/display_name_krtv_7"
-            description="@string/description_krtv_7"
-            ageHint="7">
-        </rating-definition>
-        <rating-definition id="KR_TV_12"
-            displayName="@string/display_name_krtv_12"
-            description="@string/description_krtv_12"
-            ageHint="12">
-        </rating-definition>
-        <rating-definition id="KR_TV_15"
-            displayName="@string/display_name_krtv_15"
-            description="@string/description_krtv_15"
-            ageHint="15">
-        </rating-definition>
-        <rating-definition id="KR_TV_19"
-            displayName="@string/display_name_krtv_19"
-            description="@string/description_krtv_19"
-            ageHint="19">
-        </rating-definition>
-        <order>
-            <rating id="KR_TV_ALL" />
-            <rating id="KR_TV_7" />
-            <rating id="KR_TV_12" />
-            <rating id="KR_TV_15" />
-            <rating id="KR_TV_19" />
-        </order>
-    </rating-system-definition>
+    <!-- TV content rating system for VE TV -->
+
+    <!-- TV content rating system for ZA TV -->
 </rating-system-definitions>
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/le/AdvertiseDataTest.java b/core/tests/bluetoothtests/src/android/bluetooth/le/AdvertiseDataTest.java
index 5e451ca..e58d905 100644
--- a/core/tests/bluetoothtests/src/android/bluetooth/le/AdvertiseDataTest.java
+++ b/core/tests/bluetoothtests/src/android/bluetooth/le/AdvertiseDataTest.java
@@ -66,7 +66,7 @@
         byte[] manufacturerData = new byte[0];
         AdvertiseData data =
                 mAdvertiseDataBuilder.setIncludeDeviceName(true)
-                        .setManufacturerData(manufacturerId, manufacturerData).build();
+                        .addManufacturerData(manufacturerId, manufacturerData).build();
         data.writeToParcel(parcel, 0);
         parcel.setDataPosition(0);
         AdvertiseData dataFromParcel =
@@ -81,7 +81,7 @@
         byte[] serviceData = new byte[0];
         AdvertiseData data =
                 mAdvertiseDataBuilder.setIncludeDeviceName(true)
-                        .setServiceData(uuid, serviceData).build();
+                        .addServiceData(uuid, serviceData).build();
         data.writeToParcel(parcel, 0);
         parcel.setDataPosition(0);
         AdvertiseData dataFromParcel =
@@ -117,7 +117,7 @@
         AdvertiseData data =
                 mAdvertiseDataBuilder.setIncludeDeviceName(true)
                         .addServiceUuid(uuid).addServiceUuid(uuid2)
-                        .setManufacturerData(manufacturerId, manufacturerData).build();
+                        .addManufacturerData(manufacturerId, manufacturerData).build();
 
         data.writeToParcel(parcel, 0);
         parcel.setDataPosition(0);
@@ -134,7 +134,7 @@
                 (byte) 0xF0, 0x00, 0x02, 0x15 };
         AdvertiseData data =
                 mAdvertiseDataBuilder.setIncludeDeviceName(true)
-                        .setServiceData(uuid, serviceData).build();
+                        .addServiceData(uuid, serviceData).build();
         data.writeToParcel(parcel, 0);
         parcel.setDataPosition(0);
         AdvertiseData dataFromParcel =
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/le/ScanRecordTest.java b/core/tests/bluetoothtests/src/android/bluetooth/le/ScanRecordTest.java
index ccdd90a..8b3db7e 100644
--- a/core/tests/bluetoothtests/src/android/bluetooth/le/ScanRecordTest.java
+++ b/core/tests/bluetoothtests/src/android/bluetooth/le/ScanRecordTest.java
@@ -53,13 +53,13 @@
         assertEquals("Ped", data.getDeviceName());
         assertEquals(-20, data.getTxPowerLevel());
 
-        assertEquals(0x00e0, data.getManufacturerId());
+        assertTrue(data.getManufacturerSpecificData().get(0x00E0) != null);
         assertArrayEquals(new byte[] {
-                0x02, 0x15 }, data.getManufacturerSpecificData());
+                0x02, 0x15 }, data.getManufacturerSpecificData().get(0x00E0));
 
-        assertEquals(uuid2, data.getServiceDataUuid());
+        assertTrue(data.getServiceData().containsKey(uuid2));
         assertArrayEquals(new byte[] {
-                0x50, 0x64 }, data.getServiceData());
+                0x50, 0x64 }, data.getServiceData().get(uuid2));
     }
 
     // Assert two byte arrays are equal.
diff --git a/data/fonts/Roboto-Black.ttf b/data/fonts/Roboto-Black.ttf
index 1eb7cf2..79b5f74 100644
--- a/data/fonts/Roboto-Black.ttf
+++ b/data/fonts/Roboto-Black.ttf
Binary files differ
diff --git a/data/fonts/Roboto-BlackItalic.ttf b/data/fonts/Roboto-BlackItalic.ttf
index 8f9da76..4c58b7b 100644
--- a/data/fonts/Roboto-BlackItalic.ttf
+++ b/data/fonts/Roboto-BlackItalic.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Bold.ttf b/data/fonts/Roboto-Bold.ttf
index d3a6ed9..58397cc 100644
--- a/data/fonts/Roboto-Bold.ttf
+++ b/data/fonts/Roboto-Bold.ttf
Binary files differ
diff --git a/data/fonts/Roboto-BoldItalic.ttf b/data/fonts/Roboto-BoldItalic.ttf
index 49bd012..606252c 100644
--- a/data/fonts/Roboto-BoldItalic.ttf
+++ b/data/fonts/Roboto-BoldItalic.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Italic.ttf b/data/fonts/Roboto-Italic.ttf
index da58461..cc3fd40 100644
--- a/data/fonts/Roboto-Italic.ttf
+++ b/data/fonts/Roboto-Italic.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Light.ttf b/data/fonts/Roboto-Light.ttf
index 9ca4e92..e65c2d2 100644
--- a/data/fonts/Roboto-Light.ttf
+++ b/data/fonts/Roboto-Light.ttf
Binary files differ
diff --git a/data/fonts/Roboto-LightItalic.ttf b/data/fonts/Roboto-LightItalic.ttf
index 710c14c..d5476e7 100644
--- a/data/fonts/Roboto-LightItalic.ttf
+++ b/data/fonts/Roboto-LightItalic.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Medium.ttf b/data/fonts/Roboto-Medium.ttf
index aaa3723..9263090 100644
--- a/data/fonts/Roboto-Medium.ttf
+++ b/data/fonts/Roboto-Medium.ttf
Binary files differ
diff --git a/data/fonts/Roboto-MediumItalic.ttf b/data/fonts/Roboto-MediumItalic.ttf
index 8c2b101..329aab9 100644
--- a/data/fonts/Roboto-MediumItalic.ttf
+++ b/data/fonts/Roboto-MediumItalic.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Regular.ttf b/data/fonts/Roboto-Regular.ttf
index e5b0c83..c515eca 100644
--- a/data/fonts/Roboto-Regular.ttf
+++ b/data/fonts/Roboto-Regular.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Thin.ttf b/data/fonts/Roboto-Thin.ttf
index 781ef3d..35ab525 100644
--- a/data/fonts/Roboto-Thin.ttf
+++ b/data/fonts/Roboto-Thin.ttf
Binary files differ
diff --git a/data/fonts/Roboto-ThinItalic.ttf b/data/fonts/Roboto-ThinItalic.ttf
index 0ed5203..edada2e 100644
--- a/data/fonts/Roboto-ThinItalic.ttf
+++ b/data/fonts/Roboto-ThinItalic.ttf
Binary files differ
diff --git a/data/fonts/RobotoCondensed-Bold.ttf b/data/fonts/RobotoCondensed-Bold.ttf
index 9f34ffe..bcbeece 100644
--- a/data/fonts/RobotoCondensed-Bold.ttf
+++ b/data/fonts/RobotoCondensed-Bold.ttf
Binary files differ
diff --git a/data/fonts/RobotoCondensed-BoldItalic.ttf b/data/fonts/RobotoCondensed-BoldItalic.ttf
index c8dea7a..7680d0a 100644
--- a/data/fonts/RobotoCondensed-BoldItalic.ttf
+++ b/data/fonts/RobotoCondensed-BoldItalic.ttf
Binary files differ
diff --git a/data/fonts/RobotoCondensed-Italic.ttf b/data/fonts/RobotoCondensed-Italic.ttf
index 09f4f5b..04c83a0 100644
--- a/data/fonts/RobotoCondensed-Italic.ttf
+++ b/data/fonts/RobotoCondensed-Italic.ttf
Binary files differ
diff --git a/data/fonts/RobotoCondensed-Light.ttf b/data/fonts/RobotoCondensed-Light.ttf
index c33a3e1..9f57418 100644
--- a/data/fonts/RobotoCondensed-Light.ttf
+++ b/data/fonts/RobotoCondensed-Light.ttf
Binary files differ
diff --git a/data/fonts/RobotoCondensed-LightItalic.ttf b/data/fonts/RobotoCondensed-LightItalic.ttf
index adfefc4..f9eac04 100644
--- a/data/fonts/RobotoCondensed-LightItalic.ttf
+++ b/data/fonts/RobotoCondensed-LightItalic.ttf
Binary files differ
diff --git a/data/fonts/RobotoCondensed-Regular.ttf b/data/fonts/RobotoCondensed-Regular.ttf
index d750454..3a06286 100644
--- a/data/fonts/RobotoCondensed-Regular.ttf
+++ b/data/fonts/RobotoCondensed-Regular.ttf
Binary files differ
diff --git a/docs/html/training/sync-adapters/creating-stub-provider.jd b/docs/html/training/sync-adapters/creating-stub-provider.jd
index 8f6eba0..b8190d1 100644
--- a/docs/html/training/sync-adapters/creating-stub-provider.jd
+++ b/docs/html/training/sync-adapters/creating-stub-provider.jd
@@ -190,7 +190,7 @@
     &lt;provider
         android:name="com.example.android.datasync.provider.StubProvider"
         android:authorities="com.example.android.datasync.provider"
-        android:export="false"
+        android:exported="false"
         android:syncable="true"/&gt;
     ...
     &lt;/application&gt;
diff --git a/docs/html/training/sync-adapters/creating-sync-adapter.jd b/docs/html/training/sync-adapters/creating-sync-adapter.jd
index 7c59c8c..b13ce07 100644
--- a/docs/html/training/sync-adapters/creating-sync-adapter.jd
+++ b/docs/html/training/sync-adapters/creating-sync-adapter.jd
@@ -619,7 +619,7 @@
                 android:name="com.example.android.datasync.SyncService"
                 android:exported="true"
                 android:process=":sync"&gt;
-            &lt;intent-filter&gt;com.example.android.datasync.provider
+            &lt;intent-filter&gt;
                 &lt;action android:name="android.content.SyncAdapter"/&gt;
             &lt;/intent-filter&gt;
             &lt;meta-data android:name="android.content.SyncAdapter"
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 4b00e22..4d0bb75 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.Trace;
 import android.util.DisplayMetrics;
 
 import java.io.OutputStream;
@@ -1004,8 +1005,11 @@
         if (quality < 0 || quality > 100) {
             throw new IllegalArgumentException("quality must be 0..100");
         }
-        return nativeCompress(mNativeBitmap, format.nativeInt, quality,
+        Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "Bitmap.compress");
+        boolean result = nativeCompress(mNativeBitmap, format.nativeInt, quality,
                               stream, new byte[WORKING_COMPRESS_STORAGE]);
+        Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
+        return result;
     }
 
     /**
diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java
index 3bccf08..6f42046 100644
--- a/graphics/java/android/graphics/NinePatch.java
+++ b/graphics/java/android/graphics/NinePatch.java
@@ -118,7 +118,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            nativeFinalize(mNativeChunk);
+            if (mNativeChunk != 0) {
+                // only attempt to destroy correctly initilized chunks
+                nativeFinalize(mNativeChunk);
+            }
         } finally {
             super.finalize();
         }
diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java
index 1cf5f37..3177023 100644
--- a/graphics/java/android/graphics/Outline.java
+++ b/graphics/java/android/graphics/Outline.java
@@ -92,19 +92,15 @@
     /**
      * Sets the alpha represented by the Outline.
      *
-     * Content producing a fully opaque (alpha = 1.0f) outline is assumed, by the drawing system,
+     * Content producing a fully opaque (alpha = 1.0f) outline is assumed by the drawing system
      * to fully cover content beneath it, meaning content beneath may be optimized away.
-     *
-     * @hide
      */
     public void setAlpha(float alpha) {
         mAlpha = alpha;
     }
 
     /**
-     * Sets the alpha represented by the Outline.
-     *
-     * @hide
+     * Returns the alpha represented by the Outline.
      */
     public float getAlpha() {
         return mAlpha;
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index ec862f8..ca8d736 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1305,10 +1305,13 @@
      * @hide
      */
     public void setFontFeatureSettings(String settings) {
-        if (settings != null && settings.equals(""))
+        if (settings != null && settings.equals("")) {
             settings = null;
+        }
         if ((settings == null && mFontFeatureSettings == null)
-                || (settings != null && settings.equals(mFontFeatureSettings))) return;
+                || (settings != null && settings.equals(mFontFeatureSettings))) {
+            return;
+        }
         mFontFeatureSettings = settings;
         native_setFontFeatureSettings(mNativePaint, settings);
     }
diff --git a/graphics/java/android/graphics/RadialGradient.java b/graphics/java/android/graphics/RadialGradient.java
index 9d015f7..ade14c6 100644
--- a/graphics/java/android/graphics/RadialGradient.java
+++ b/graphics/java/android/graphics/RadialGradient.java
@@ -16,6 +16,9 @@
 
 package android.graphics;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
 public class RadialGradient extends Shader {
 
     private static final int TYPE_COLORS_AND_POSITIONS = 1;
@@ -32,63 +35,64 @@
     private float mRadius;
     private int[] mColors;
     private float[] mPositions;
-    private int mColor0;
-    private int mColor1;
+    private int mCenterColor;
+    private int mEdgeColor;
 
     private TileMode mTileMode;
 
     /** Create a shader that draws a radial gradient given the center and radius.
-        @param x        The x-coordinate of the center of the radius
-        @param y        The y-coordinate of the center of the radius
-        @param radius   Must be positive. The radius of the circle for this gradient
+        @param centerX  The x-coordinate of the center of the radius
+        @param centerY  The y-coordinate of the center of the radius
+        @param radius   Must be positive. The radius of the circle for this gradient.
         @param colors   The colors to be distributed between the center and edge of the circle
-        @param positions May be NULL. The relative position of
-                        each corresponding color in the colors array. If this is NULL,
-                        the the colors are distributed evenly between the center and edge of the circle.
-        @param  tile    The Shader tiling mode
+        @param stops    May be <code>null</code>. Valid values are between <code>0.0f</code> and
+                        <code>1.0f</code>. The relative position of each corresponding color in
+                        the colors array. If <code>null</code>, colors are distributed evenly
+                        between the center and edge of the circle.
+        @param tileMode The Shader tiling mode
     */
-    public RadialGradient(float x, float y, float radius,
-                          int colors[], float positions[], TileMode tile) {
+    public RadialGradient(float centerX, float centerY, float radius,
+               @NonNull int colors[], @Nullable float stops[], @NonNull TileMode tileMode) {
         if (radius <= 0) {
             throw new IllegalArgumentException("radius must be > 0");
         }
         if (colors.length < 2) {
             throw new IllegalArgumentException("needs >= 2 number of colors");
         }
-        if (positions != null && colors.length != positions.length) {
+        if (stops != null && colors.length != stops.length) {
             throw new IllegalArgumentException("color and position arrays must be of equal length");
         }
         mType = TYPE_COLORS_AND_POSITIONS;
-        mX = x;
-        mY = y;
+        mX = centerX;
+        mY = centerY;
         mRadius = radius;
         mColors = colors;
-        mPositions = positions;
-        mTileMode = tile;
-        init(nativeCreate1(x, y, radius, colors, positions, tile.nativeInt));
+        mPositions = stops;
+        mTileMode = tileMode;
+        init(nativeCreate1(centerX, centerY, radius, colors, stops, tileMode.nativeInt));
     }
 
     /** Create a shader that draws a radial gradient given the center and radius.
-        @param x        The x-coordinate of the center of the radius
-        @param y        The y-coordinate of the center of the radius
-        @param radius   Must be positive. The radius of the circle for this gradient
-        @param color0   The color at the center of the circle.
-        @param color1   The color at the edge of the circle.
-        @param tile     The Shader tiling mode
+        @param centerX     The x-coordinate of the center of the radius
+        @param centerY     The y-coordinate of the center of the radius
+        @param radius      Must be positive. The radius of the circle for this gradient
+        @param centerColor The color at the center of the circle.
+        @param edgeColor   The color at the edge of the circle.
+        @param tileMode    The Shader tiling mode
     */
-    public RadialGradient(float x, float y, float radius,
-                          int color0, int color1, TileMode tile) {
+    public RadialGradient(float centerX, float centerY, float radius,
+            int centerColor, int edgeColor, @NonNull TileMode tileMode) {
         if (radius <= 0) {
             throw new IllegalArgumentException("radius must be > 0");
         }
         mType = TYPE_COLOR_CENTER_AND_COLOR_EDGE;
-        mX = x;
-        mY = y;
+        mX = centerX;
+        mY = centerY;
         mRadius = radius;
-        mColor0 = color0;
-        mColor1 = color1;
-        mTileMode = tile;
-        init(nativeCreate2(x, y, radius, color0, color1, tile.nativeInt));
+        mCenterColor = centerColor;
+        mEdgeColor = edgeColor;
+        mTileMode = tileMode;
+        init(nativeCreate2(centerX, centerY, radius, centerColor, edgeColor, tileMode.nativeInt));
     }
 
     /**
@@ -103,7 +107,7 @@
                         mPositions != null ? mPositions.clone() : null, mTileMode);
                 break;
             case TYPE_COLOR_CENTER_AND_COLOR_EDGE:
-                copy = new RadialGradient(mX, mY, mRadius, mColor0, mColor1, mTileMode);
+                copy = new RadialGradient(mX, mY, mRadius, mCenterColor, mEdgeColor, mTileMode);
                 break;
             default:
                 throw new IllegalArgumentException("RadialGradient should be created with either " +
diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
index 0fd4423..e3c03a9 100644
--- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
@@ -171,8 +171,13 @@
     }
 
     @Override
-    public void setTint(ColorStateList tint, Mode tintMode) {
-        mState.mDrawable.setTint(tint, tintMode);
+    public void setTintList(ColorStateList tint) {
+        mState.mDrawable.setTintList(tint);
+    }
+
+    @Override
+    public void setTintMode(Mode tintMode) {
+        mState.mDrawable.setTintMode(tintMode);
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 54683aa..00c92fa 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -312,9 +312,7 @@
         final int size = animators.size();
         for (int i = 0; i < size; i++) {
             final Animator animator = animators.get(i);
-            if (animator.isPaused()) {
-                animator.resume();
-            } else if (!animator.isRunning()) {
+            if (!animator.isRunning()) {
                 animator.start();
             }
         }
@@ -327,7 +325,7 @@
         final int size = animators.size();
         for (int i = 0; i < size; i++) {
             final Animator animator = animators.get(i);
-            animator.pause();
+            animator.end();
         }
     }
 
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 525e01d..f5e63ae 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -623,12 +623,16 @@
     }
 
     @Override
-    public void setTint(ColorStateList tint, PorterDuff.Mode tintMode) {
-        final BitmapState state = mBitmapState;
-        state.mTint = tint;
-        state.mTintMode = tintMode;
+    public void setTintList(ColorStateList tint) {
+        mBitmapState.mTint = tint;
+        mTintFilter = updateTintFilter(mTintFilter, tint, mBitmapState.mTintMode);
+        invalidateSelf();
+    }
 
-        mTintFilter = updateTintFilter(mTintFilter, tint, tintMode);
+    @Override
+    public void setTintMode(PorterDuff.Mode tintMode) {
+        mBitmapState.mTintMode = tintMode;
+        mTintFilter = updateTintFilter(mTintFilter, mBitmapState.mTint, tintMode);
         invalidateSelf();
     }
 
diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java
index 174de3a..f116376 100644
--- a/graphics/java/android/graphics/drawable/ClipDrawable.java
+++ b/graphics/java/android/graphics/drawable/ClipDrawable.java
@@ -174,8 +174,13 @@
     }
 
     @Override
-    public void setTint(ColorStateList tint, Mode tintMode) {
-        mClipState.mDrawable.setTint(tint, tintMode);
+    public void setTintList(ColorStateList tint) {
+        mClipState.mDrawable.setTintList(tint);
+    }
+
+    @Override
+    public void setTintMode(Mode tintMode) {
+        mClipState.mDrawable.setTintMode(tintMode);
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index 4f050e0..9e42a89 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -167,15 +167,17 @@
     }
 
     @Override
-    public void setTint(ColorStateList tint, Mode tintMode) {
-        final ColorState state = mColorState;
-        if (state.mTint != tint || state.mTintMode != tintMode) {
-            state.mTint = tint;
-            state.mTintMode = tintMode;
+    public void setTintList(ColorStateList tint) {
+        mColorState.mTint = tint;
+        mTintFilter = updateTintFilter(mTintFilter, tint, mColorState.mTintMode);
+        invalidateSelf();
+    }
 
-            mTintFilter = updateTintFilter(mTintFilter, tint, tintMode);
-            invalidateSelf();
-        }
+    @Override
+    public void setTintMode(Mode tintMode) {
+        mColorState.mTintMode = tintMode;
+        mTintFilter = updateTintFilter(mTintFilter, mColorState.mTint, tintMode);
+        invalidateSelf();
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index df9f3c3..5a3e3a3 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -478,10 +478,48 @@
      * @param tint Color state list to use for tinting this drawable, or null to
      *            clear the tint
      * @param tintMode A Porter-Duff blending mode
+     * @hide TODO: Was in L-preview, remove this API for release
      */
     public void setTint(ColorStateList tint, PorterDuff.Mode tintMode) {}
 
     /**
+     * Specifies a tint for this drawable.
+     * <p>
+     * Setting a color filter via {@link #setColorFilter(ColorFilter)} overrides
+     * tint.
+     *
+     * @param tint Color to use for tinting this drawable
+     * @see #setTintMode(PorterDuff.Mode)
+     */
+    public void setTint(int tint) {
+        setTintList(ColorStateList.valueOf(tint));
+    }
+
+    /**
+     * Specifies a tint for this drawable as a color state list.
+     * <p>
+     * Setting a color filter via {@link #setColorFilter(ColorFilter)} overrides
+     * tint.
+     *
+     * @param tint Color state list to use for tinting this drawable, or null to
+     *            clear the tint
+     * @see #setTintMode(PorterDuff.Mode)
+     */
+    public void setTintList(ColorStateList tint) {}
+
+    /**
+     * Specifies a tint blending mode for this drawable.
+     * <p>
+     * Setting a color filter via {@link #setColorFilter(ColorFilter)} overrides
+     * tint.
+     *
+     * @param tintMode Color state list to use for tinting this drawable, or null to
+     *            clear the tint
+     * @param tintMode A Porter-Duff blending mode
+     */
+    public void setTintMode(PorterDuff.Mode tintMode) {}
+
+    /**
      * Returns the current color filter, or {@code null} if none set.
      *
      * @return the current color filter, or {@code null} if none set
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 55bc35e..0b052f4 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -176,15 +176,29 @@
     }
 
     @Override
-    public void setTint(ColorStateList tint, Mode tintMode) {
-        mDrawableContainerState.mHasTint = (tint != null && tintMode != null);
+    public void setTintList(ColorStateList tint) {
+        mDrawableContainerState.mHasTint = tint != null
+                && mDrawableContainerState.mTintMode != null;
 
-        if (mDrawableContainerState.mTint != tint || mDrawableContainerState.mTintMode != tintMode) {
+        if (mDrawableContainerState.mTint != tint) {
             mDrawableContainerState.mTint = tint;
+
+            if (mCurrDrawable != null) {
+                mCurrDrawable.mutate().setTintList(tint);
+            }
+        }
+    }
+
+    @Override
+    public void setTintMode(Mode tintMode) {
+        mDrawableContainerState.mHasTint = mDrawableContainerState.mTint != null
+                && tintMode != null;
+
+        if (mDrawableContainerState.mTintMode != tintMode) {
             mDrawableContainerState.mTintMode = tintMode;
 
             if (mCurrDrawable != null) {
-                mCurrDrawable.mutate().setTint(tint, tintMode);
+                mCurrDrawable.mutate().setTintMode(tintMode);
             }
         }
     }
@@ -437,7 +451,8 @@
                 if (mDrawableContainerState.mHasColorFilter) {
                     d.setColorFilter(mDrawableContainerState.mColorFilter);
                 } else if (mDrawableContainerState.mHasTint) {
-                    d.setTint(mDrawableContainerState.mTint, mDrawableContainerState.mTintMode);
+                    d.setTintList(mDrawableContainerState.mTint);
+                    d.setTintMode(mDrawableContainerState.mTintMode);
                 }
                 d.setVisible(isVisible(), true);
                 d.setDither(mDrawableContainerState.mDither);
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index f6ccbf5..ee5fe2e 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -260,8 +260,13 @@
     }
 
     @Override
-    public void setTint(ColorStateList tint, Mode tintMode) {
-        mInsetState.mDrawable.setTint(tint, tintMode);
+    public void setTintList(ColorStateList tint) {
+        mInsetState.mDrawable.setTintList(tint);
+    }
+
+    @Override
+    public void setTintMode(Mode tintMode) {
+        mInsetState.mDrawable.setTintMode(tintMode);
     }
 
     /** {@hide} */
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index d094ce4..43bc89a 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -698,11 +698,20 @@
     }
 
     @Override
-    public void setTint(ColorStateList tint, Mode tintMode) {
+    public void setTintList(ColorStateList tint) {
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
         for (int i = 0; i < N; i++) {
-            array[i].mDrawable.setTint(tint, tintMode);
+            array[i].mDrawable.setTintList(tint);
+        }
+    }
+
+    @Override
+    public void setTintMode(Mode tintMode) {
+        final ChildDrawable[] array = mLayerState.mChildren;
+        final int N = mLayerState.mNum;
+        for (int i = 0; i < N; i++) {
+            array[i].mDrawable.setTintMode(tintMode);
         }
     }
 
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 3397e94..6ebb8b5 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -346,12 +346,16 @@
     }
 
     @Override
-    public void setTint(ColorStateList tint, PorterDuff.Mode tintMode) {
-        final NinePatchState state = mNinePatchState;
-        state.mTint = tint;
-        state.mTintMode = tintMode;
+    public void setTintList(ColorStateList tint) {
+        mNinePatchState.mTint = tint;
+        mTintFilter = updateTintFilter(mTintFilter, tint, mNinePatchState.mTintMode);
+        invalidateSelf();
+    }
 
-        mTintFilter = updateTintFilter(mTintFilter, tint, tintMode);
+    @Override
+    public void setTintMode(PorterDuff.Mode tintMode) {
+        mNinePatchState.mTintMode = tintMode;
+        mTintFilter = updateTintFilter(mTintFilter, mNinePatchState.mTint, tintMode);
         invalidateSelf();
     }
 
@@ -613,10 +617,10 @@
             this(ninePatch, padding, opticalInsets, DEFAULT_DITHER, false);
         }
 
-        NinePatchState(NinePatch ninePatch, Rect rect, Rect opticalInsets, boolean dither,
+        NinePatchState(NinePatch ninePatch, Rect padding, Rect opticalInsets, boolean dither,
                 boolean autoMirror) {
             mNinePatch = ninePatch;
-            mPadding = rect;
+            mPadding = padding;
             mOpticalInsets = Insets.of(opticalInsets);
             mDither = dither;
             mAutoMirrored = autoMirror;
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index 8f8fa98..983eb3b 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -139,8 +139,13 @@
     }
 
     @Override
-    public void setTint(ColorStateList tint, Mode tintMode) {
-        mState.mDrawable.setTint(tint, tintMode);
+    public void setTintList(ColorStateList tint) {
+        mState.mDrawable.setTintList(tint);
+    }
+
+    @Override
+    public void setTintMode(Mode tintMode) {
+        mState.mDrawable.setTintMode(tintMode);
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index 46c92fe..a954474 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -190,8 +190,13 @@
     }
 
     @Override
-    public void setTint(ColorStateList tint, Mode tintMode) {
-        mScaleState.mDrawable.setTint(tint, tintMode);
+    public void setTintList(ColorStateList tint) {
+        mScaleState.mDrawable.setTintList(tint);
+    }
+
+    @Override
+    public void setTintMode(Mode tintMode) {
+        mScaleState.mDrawable.setTintMode(tintMode);
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 394f584..6f18635 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -285,12 +285,16 @@
     }
 
     @Override
-    public void setTint(ColorStateList tint, PorterDuff.Mode tintMode) {
-        final ShapeState state = mShapeState;
-        state.mTint = tint;
-        state.mTintMode = tintMode;
+    public void setTintList(ColorStateList tint) {
+        mShapeState.mTint = tint;
+        mTintFilter = updateTintFilter(mTintFilter, tint, mShapeState.mTintMode);
+        invalidateSelf();
+    }
 
-        mTintFilter = updateTintFilter(mTintFilter, tint, tintMode);
+    @Override
+    public void setTintMode(PorterDuff.Mode tintMode) {
+        mShapeState.mTintMode = tintMode;
+        mTintFilter = updateTintFilter(mTintFilter, mShapeState.mTint, tintMode);
         invalidateSelf();
     }
 
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index be02c9b..813797f 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -307,14 +307,23 @@
     }
 
     @Override
-    public void setTint(ColorStateList tint, Mode tintMode) {
+    public void setTintList(ColorStateList tint) {
         final VectorDrawableState state = mVectorState;
-        if (state.mTint != tint || state.mTintMode != tintMode) {
+        if (state.mTint != tint) {
             state.mTint = tint;
-            state.mTintMode = tintMode;
+            mTintFilter = updateTintFilter(mTintFilter, tint, state.mTintMode);
+            state.mVPathRenderer.setColorFilter(mTintFilter);
+            invalidateSelf();
+        }
+    }
 
-            mTintFilter = updateTintFilter(mTintFilter, tint, tintMode);
-            mVectorState.mVPathRenderer.setColorFilter(mTintFilter);
+    @Override
+    public void setTintMode(Mode tintMode) {
+        final VectorDrawableState state = mVectorState;
+        if (state.mTintMode != tintMode) {
+            state.mTintMode = tintMode;
+            mTintFilter = updateTintFilter(mTintFilter, state.mTint, tintMode);
+            state.mVPathRenderer.setColorFilter(mTintFilter);
             invalidateSelf();
         }
     }
@@ -708,7 +717,7 @@
             mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap);
             mBaseWidth = copy.mBaseWidth;
             mBaseHeight = copy.mBaseHeight;
-            mViewportWidth = copy.mViewportHeight;
+            mViewportWidth = copy.mViewportWidth;
             mViewportHeight = copy.mViewportHeight;
             mChangingConfigurations = copy.mChangingConfigurations;
             mRootAlpha = copy.mRootAlpha;
@@ -883,7 +892,7 @@
                         strokePaint.setStrokeCap(fullPath.mStrokeLineCap);
                     }
 
-                    strokePaint.setStrokeMiter(fullPath.mStrokeMiterlimit * minScale);
+                    strokePaint.setStrokeMiter(fullPath.mStrokeMiterlimit);
 
                     strokePaint.setColor(applyAlpha(fullPath.mStrokeColor, stackedAlpha));
                     strokePaint.setStrokeWidth(fullPath.mStrokeWidth * minScale);
diff --git a/include/android_runtime/AndroidRuntime.h b/include/android_runtime/AndroidRuntime.h
index 45aa745..51e47e6 100644
--- a/include/android_runtime/AndroidRuntime.h
+++ b/include/android_runtime/AndroidRuntime.h
@@ -116,10 +116,15 @@
 
 private:
     static int startReg(JNIEnv* env);
+    void addOption(const char* optionString, void* extra_info = NULL);
     bool parseRuntimeOption(const char* property,
                             char* buffer,
                             const char* runtimeArg,
                             const char* defaultArg = "");
+    bool parseCompilerOption(const char* property,
+                             char* buffer,
+                             const char* compilerArg,
+                             const char* quotingArg);
     bool parseCompilerRuntimeOption(const char* property,
                                     char* buffer,
                                     const char* runtimeArg,
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 548ec91..7bd0798 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -699,9 +699,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void Caches::initTempProperties() {
-    propertyAmbientShadowStrength = 12;
-    propertySpotShadowStrength = 48;
-
     propertyLightDiameter = -1.0f;
     propertyLightPosY = -1.0f;
     propertyLightPosZ = -1.0f;
@@ -710,15 +707,7 @@
 
 void Caches::setTempProperty(const char* name, const char* value) {
     ALOGD("setting property %s to %s", name, value);
-    if (!strcmp(name, "ambientShadowStrength")) {
-        propertyAmbientShadowStrength = atoi(value);
-        ALOGD("ambient shadow strength = 0x%x out of 0xff", propertyAmbientShadowStrength);
-        return;
-    } else if (!strcmp(name, "spotShadowStrength")) {
-        propertySpotShadowStrength = atoi(value);
-        ALOGD("spot shadow strength = 0x%x out of 0xff", propertySpotShadowStrength);
-        return;
-    } else if (!strcmp(name, "ambientRatio")) {
+    if (!strcmp(name, "ambientRatio")) {
         propertyAmbientRatio = fmin(fmax(atof(value), 0.0), 10.0);
         ALOGD("ambientRatio = %.2f", propertyAmbientRatio);
         return;
@@ -734,10 +723,6 @@
         propertyLightPosZ = fmin(fmax(atof(value), 0.0), 3000.0);
         ALOGD("lightPos Z = %.2f", propertyLightPosZ);
         return;
-    } else if (!strcmp(name, "extraRasterBucket")) {
-        float bucket = atof(value);
-        propertyExtraRasterBuckets.push_back(bucket);
-        return;
     }
     ALOGD("    failed");
 }
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 8727941..e00cb0b 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -366,9 +366,6 @@
     float propertyLightPosY;
     float propertyLightPosZ;
     float propertyAmbientRatio;
-    int propertyAmbientShadowStrength;
-    int propertySpotShadowStrength;
-    std::vector<float> propertyExtraRasterBuckets;
 private:
     enum OverdrawColorSet {
         kColorSet_Default = 0,
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 777a35a..6883cc5 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -639,9 +639,10 @@
 
 class DrawBitmapOp : public DrawBoundedOp {
 public:
-    DrawBitmapOp(const SkBitmap* bitmap, float left, float top, const SkPaint* paint)
-            : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(), paint),
-            mBitmap(bitmap), mAtlas(Caches::getInstance().assetAtlas) {
+    DrawBitmapOp(const SkBitmap* bitmap, const SkPaint* paint)
+            : DrawBoundedOp(0, 0, bitmap->width(), bitmap->height(), paint)
+            , mBitmap(bitmap)
+            , mAtlas(Caches::getInstance().assetAtlas) {
         mEntry = mAtlas.getEntry(bitmap);
         if (mEntry) {
             mEntryGenerationId = mAtlas.getGenerationId();
@@ -650,8 +651,7 @@
     }
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
-        return renderer.drawBitmap(mBitmap, mLocalBounds.left, mLocalBounds.top,
-                getPaint(renderer));
+        return renderer.drawBitmap(mBitmap, getPaint(renderer));
     }
 
     AssetAtlas::Entry* getAtlasEntry() {
@@ -745,35 +745,6 @@
     UvMapper mUvMapper;
 };
 
-class DrawBitmapMatrixOp : public DrawBoundedOp {
-public:
-    DrawBitmapMatrixOp(const SkBitmap* bitmap, const SkMatrix& matrix, const SkPaint* paint)
-            : DrawBoundedOp(paint), mBitmap(bitmap), mMatrix(matrix) {
-        mLocalBounds.set(0, 0, bitmap->width(), bitmap->height());
-        const mat4 transform(matrix);
-        transform.mapRect(mLocalBounds);
-    }
-
-    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
-        return renderer.drawBitmap(mBitmap, mMatrix, getPaint(renderer));
-    }
-
-    virtual void output(int level, uint32_t logFlags) const {
-        OP_LOG("Draw bitmap %p matrix " SK_MATRIX_STRING, mBitmap, SK_MATRIX_ARGS(&mMatrix));
-    }
-
-    virtual const char* name() { return "DrawBitmapMatrix"; }
-
-    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
-            const DeferredDisplayState& state) {
-        deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
-    }
-
-private:
-    const SkBitmap* mBitmap;
-    const SkMatrix mMatrix;
-};
-
 class DrawBitmapRectOp : public DrawBoundedOp {
 public:
     DrawBitmapRectOp(const SkBitmap* bitmap,
@@ -807,12 +778,11 @@
 
 class DrawBitmapDataOp : public DrawBitmapOp {
 public:
-    DrawBitmapDataOp(const SkBitmap* bitmap, float left, float top, const SkPaint* paint)
-            : DrawBitmapOp(bitmap, left, top, paint) {}
+    DrawBitmapDataOp(const SkBitmap* bitmap, const SkPaint* paint)
+            : DrawBitmapOp(bitmap, paint) {}
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
-        return renderer.drawBitmapData(mBitmap, mLocalBounds.left,
-                mLocalBounds.top, getPaint(renderer));
+        return renderer.drawBitmapData(mBitmap, getPaint(renderer));
     }
 
     virtual void output(int level, uint32_t logFlags) const {
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 5286ef8..b210e64 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -194,51 +194,42 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float left, float top,
-        const SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
     bitmap = refBitmap(bitmap);
     paint = refPaint(paint);
 
-    addDrawOp(new (alloc()) DrawBitmapOp(bitmap, left, top, paint));
-    return DrawGlInfo::kStatusDone;
-}
-
-status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkMatrix& matrix,
-        const SkPaint* paint) {
-    bitmap = refBitmap(bitmap);
-    paint = refPaint(paint);
-
-    addDrawOp(new (alloc()) DrawBitmapMatrixOp(bitmap, matrix, paint));
+    addDrawOp(new (alloc()) DrawBitmapOp(bitmap, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
         float srcRight, float srcBottom, float dstLeft, float dstTop,
         float dstRight, float dstBottom, const SkPaint* paint) {
-    bitmap = refBitmap(bitmap);
-    paint = refPaint(paint);
-
-    if (srcLeft == 0 && srcTop == 0 &&
-            srcRight == bitmap->width() && srcBottom == bitmap->height() &&
-            (srcBottom - srcTop == dstBottom - dstTop) &&
-            (srcRight - srcLeft == dstRight - dstLeft)) {
+    if (srcLeft == 0 && srcTop == 0
+            && srcRight == bitmap->width() && srcBottom == bitmap->height()
+            && (srcBottom - srcTop == dstBottom - dstTop)
+            && (srcRight - srcLeft == dstRight - dstLeft)) {
         // transform simple rect to rect drawing case into position bitmap ops, since they merge
-        addDrawOp(new (alloc()) DrawBitmapOp(bitmap, dstLeft, dstTop, paint));
-        return DrawGlInfo::kStatusDone;
-    }
+        save(SkCanvas::kMatrix_SaveFlag);
+        translate(dstLeft, dstTop);
+        drawBitmap(bitmap, paint);
+        restore();
+    } else {
+        bitmap = refBitmap(bitmap);
+        paint = refPaint(paint);
 
-    addDrawOp(new (alloc()) DrawBitmapRectOp(bitmap,
-                    srcLeft, srcTop, srcRight, srcBottom,
-                    dstLeft, dstTop, dstRight, dstBottom, paint));
+        addDrawOp(new (alloc()) DrawBitmapRectOp(bitmap,
+                srcLeft, srcTop, srcRight, srcBottom,
+                dstLeft, dstTop, dstRight, dstBottom, paint));
+    }
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, float left, float top,
-        const SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) {
     bitmap = refBitmapData(bitmap);
     paint = refPaint(paint);
 
-    addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, left, top, paint));
+    addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, paint));
     return DrawGlInfo::kStatusDone;
 }
 
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index d1d8572..1b3a48a 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -105,15 +105,11 @@
     virtual status_t drawColor(int color, SkXfermode::Mode mode);
 
     // Bitmap-based
-    virtual status_t drawBitmap(const SkBitmap* bitmap, float left, float top,
-            const SkPaint* paint);
-    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkMatrix& matrix,
-            const SkPaint* paint);
+    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
     virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
             float dstRight, float dstBottom, const SkPaint* paint);
-    virtual status_t drawBitmapData(const SkBitmap* bitmap, float left, float top,
-            const SkPaint* paint);
+    virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint);
     virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
             const float* vertices, const int* colors, const SkPaint* paint);
     virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 5e6ae3f..e00d2e3 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2034,12 +2034,8 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, float left, float top,
-        const SkPaint* paint) {
-    const float right = left + bitmap->width();
-    const float bottom = top + bitmap->height();
-
-    if (quickRejectSetupScissor(left, top, right, bottom)) {
+status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
+    if (quickRejectSetupScissor(0, 0, bitmap->width(), bitmap->height())) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2049,49 +2045,16 @@
     const AutoTexture autoCleanup(texture);
 
     if (CC_UNLIKELY(bitmap->colorType() == kAlpha_8_SkColorType)) {
-        drawAlphaBitmap(texture, left, top, paint);
+        drawAlphaBitmap(texture, 0, 0, paint);
     } else {
-        drawTextureRect(left, top, right, bottom, texture, paint);
+        drawTextureRect(0, 0, bitmap->width(), bitmap->height(), texture, paint);
     }
 
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkMatrix& matrix,
-        const SkPaint* paint) {
-    Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
-    const mat4 transform(matrix);
-    transform.mapRect(r);
-
-    if (quickRejectSetupScissor(r.left, r.top, r.right, r.bottom)) {
-        return DrawGlInfo::kStatusDone;
-    }
-
-    mCaches.activeTexture(0);
-    Texture* texture = getTexture(bitmap);
-    if (!texture) return DrawGlInfo::kStatusDone;
-    const AutoTexture autoCleanup(texture);
-
-    // This could be done in a cheaper way, all we need is pass the matrix
-    // to the vertex shader. The save/restore is a bit overkill.
-    save(SkCanvas::kMatrix_SaveFlag);
-    concatMatrix(matrix);
-    if (CC_UNLIKELY(bitmap->colorType() == kAlpha_8_SkColorType)) {
-        drawAlphaBitmap(texture, 0.0f, 0.0f, paint);
-    } else {
-        drawTextureRect(0.0f, 0.0f, bitmap->width(), bitmap->height(), texture, paint);
-    }
-    restore();
-
-    return DrawGlInfo::kStatusDrew;
-}
-
-status_t OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, float left, float top,
-        const SkPaint* paint) {
-    const float right = left + bitmap->width();
-    const float bottom = top + bitmap->height();
-
-    if (quickRejectSetupScissor(left, top, right, bottom)) {
+status_t OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) {
+    if (quickRejectSetupScissor(0, 0, bitmap->width(), bitmap->height())) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2100,9 +2063,9 @@
     const AutoTexture autoCleanup(texture);
 
     if (CC_UNLIKELY(bitmap->colorType() == kAlpha_8_SkColorType)) {
-        drawAlphaBitmap(texture, left, top, paint);
+        drawAlphaBitmap(texture, 0, 0, paint);
     } else {
-        drawTextureRect(left, top, right, bottom, texture, paint);
+        drawTextureRect(0, 0, bitmap->width(), bitmap->height(), texture, paint);
     }
 
     return DrawGlInfo::kStatusDrew;
@@ -2809,31 +2772,15 @@
     }
 
     /**
-     * Input is a non-perspective, scaling transform. Generate a scale-only transform, based upon
-     * bucketed scale values. Special case for 'extra raster buckets' - disable filtration in the
-     * case of an exact match, and isSimple() transform
+     * Input is a non-perspective, scaling transform. Generate a scale-only transform,
+     * with values rounded to the nearest int.
      */
     float sx, sy;
     transform.decomposeScale(sx, sy);
-
-    float bestSx = roundf(fmaxf(1.0f, sx));
-    float bestSy = roundf(fmaxf(1.0f, sy));
-    bool filter = true;
-
-    for (unsigned int i = 0; i < mCaches.propertyExtraRasterBuckets.size(); i++) {
-        float bucket = mCaches.propertyExtraRasterBuckets[i];
-        if (sx == bucket && sy == bucket) {
-            bestSx = bestSy = bucket;
-            filter = !transform.isSimple(); // disable filter, if simple
-            break;
-        }
-
-        if (fabs(bucket - sx) < fabs(bestSx - sx)) bestSx = sx;
-        if (fabs(bucket - sy) < fabs(bestSy - sy)) bestSy = sy;
-    }
-
-    outMatrix->setScale(bestSx, bestSy);
-    return filter;
+    outMatrix->setScale(
+            roundf(fmaxf(1.0f, sx)),
+            roundf(fmaxf(1.0f, sy)));
+    return true;
 }
 
 status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y,
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 3bc591f..fd228db 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -161,17 +161,13 @@
 
     virtual status_t drawRenderNode(RenderNode* displayList, Rect& dirty, int32_t replayFlags = 1);
     virtual status_t drawLayer(Layer* layer, float x, float y);
-    virtual status_t drawBitmap(const SkBitmap* bitmap, float left, float top,
-            const SkPaint* paint);
+    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
     status_t drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount,
             TextureVertex* vertices, bool pureTranslate, const Rect& bounds, const SkPaint* paint);
-    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkMatrix& matrix,
-            const SkPaint* paint);
     virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
             float dstRight, float dstBottom, const SkPaint* paint);
-    virtual status_t drawBitmapData(const SkBitmap* bitmap, float left, float top,
-            const SkPaint* paint);
+    virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint);
     virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
             const float* vertices, const int* colors, const SkPaint* paint);
     status_t drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index f451690..3ef2a71 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -334,8 +334,10 @@
 const char* gFS_Main_FragColor_HasRoundRectClip =
         "    mediump vec2 fragToLT = roundRectInnerRectLTRB.xy - roundRectPos;\n"
         "    mediump vec2 fragFromRB = roundRectPos - roundRectInnerRectLTRB.zw;\n"
-        "    mediump vec2 dist = max(max(fragToLT, fragFromRB), vec2(0.0, 0.0));\n"
-        "    mediump float linearDist = roundRectRadius - length(dist);\n"
+
+        // divide + multiply by 128 to avoid falling out of range in length() function
+        "    mediump vec2 dist = max(max(fragToLT, fragFromRB), vec2(0.0, 0.0)) / 128.0;\n"
+        "    mediump float linearDist = roundRectRadius - (length(dist) * 128.0);\n"
         "    gl_FragColor *= clamp(linearDist, 0.0, 1.0);\n";
 
 const char* gFS_Main_DebugHighlight =
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index fa1b21d..f48b774 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -94,8 +94,10 @@
 
     properties().debugOutputProperties(level);
     int flags = DisplayListOp::kOpLogFlag_Recurse;
-    for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
-        mDisplayListData->displayListOps[i]->output(level, flags);
+    if (mDisplayListData) {
+        for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
+            mDisplayListData->displayListOps[i]->output(level, flags);
+        }
     }
 
     ALOGD("%*sDone (%p, %s)", (level - 1) * 2, "", this, getName());
@@ -184,7 +186,9 @@
         return;
     }
 
-    if (!dirty.isEmpty()) {
+
+    if (dirty.intersect(0, 0, getWidth(), getHeight())) {
+        dirty.roundOut();
         mLayer->updateDeferred(this, dirty.fLeft, dirty.fTop, dirty.fRight, dirty.fBottom);
     }
     // This is not inside the above if because we may have called
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index 9898bde..41f48cd 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -209,7 +209,7 @@
     }
 
     bool setAlpha(float alpha) {
-        alpha = fminf(1.0f, fmaxf(0.0f, alpha));
+        alpha = MathUtils::clampAlpha(alpha);
         return RP_SET(mPrimitiveFields.mAlpha, alpha);
     }
 
diff --git a/libs/hwui/Renderer.h b/libs/hwui/Renderer.h
index 40a21e4..f5cd266 100644
--- a/libs/hwui/Renderer.h
+++ b/libs/hwui/Renderer.h
@@ -160,15 +160,11 @@
     virtual status_t drawColor(int color, SkXfermode::Mode mode) = 0;
 
     // Bitmap-based
-    virtual status_t drawBitmap(const SkBitmap* bitmap, float left, float top,
-            const SkPaint* paint) = 0;
-    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkMatrix& matrix,
-            const SkPaint* paint) = 0;
+    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) = 0;
     virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
             float dstRight, float dstBottom, const SkPaint* paint) = 0;
-    virtual status_t drawBitmapData(const SkBitmap* bitmap, float left, float top,
-            const SkPaint* paint) = 0;
+    virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) = 0;
     virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
             const float* vertices, const int* colors, const SkPaint* paint) = 0;
     virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 3f03093..986e808 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -336,11 +336,14 @@
 }
 
 void RenderProxy::trimMemory(int level) {
-    RenderThread& thread = RenderThread::getInstance();
-    SETUP_TASK(timMemory);
-    args->thread = &thread;
-    args->level = level;
-    thread.queue(task);
+    // Avoid creating a RenderThread to do a trimMemory.
+    if (RenderThread::hasInstance()) {
+        RenderThread& thread = RenderThread::getInstance();
+        SETUP_TASK(timMemory);
+        args->thread = &thread;
+        args->level = level;
+        thread.queue(task);
+    }
 }
 
 CREATE_BRIDGE0(fence) {
diff --git a/libs/hwui/utils/MathUtils.h b/libs/hwui/utils/MathUtils.h
index 2dfe9c6..66bc127 100644
--- a/libs/hwui/utils/MathUtils.h
+++ b/libs/hwui/utils/MathUtils.h
@@ -20,6 +20,7 @@
 namespace uirenderer {
 
 #define NON_ZERO_EPSILON (0.001f)
+#define ALPHA_EPSILON (0.001f)
 
 class MathUtils {
 public:
@@ -34,6 +35,16 @@
         return value >= NON_ZERO_EPSILON;
     }
 
+    inline static float clampAlpha(float alpha) {
+        if (alpha <= ALPHA_EPSILON) {
+            return 0;
+        } else if (alpha >= (1 - ALPHA_EPSILON)) {
+            return 1;
+        } else {
+            return alpha;
+        }
+    }
+
     inline static bool areEqual(float valueA, float valueB) {
         return isZero(valueA - valueB);
     }
diff --git a/libs/usb/tests/accessorytest/Android.mk b/libs/usb/tests/accessorytest/Android.mk
new file mode 100644
index 0000000..6d9a946
--- /dev/null
+++ b/libs/usb/tests/accessorytest/Android.mk
@@ -0,0 +1,25 @@
+LOCAL_PATH:= $(call my-dir)
+
+# Build for Linux host only
+ifeq ($(HOST_OS),linux)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES :=  accessory.c \
+                    audio.c     \
+                    hid.c       \
+                    usb.c
+
+LOCAL_C_INCLUDES += external/tinyalsa/include
+
+LOCAL_MODULE := accessorytest
+
+LOCAL_STATIC_LIBRARIES := libusbhost libcutils libtinyalsa
+LOCAL_LDLIBS += -lpthread
+LOCAL_CFLAGS := -g -O0
+
+include $(BUILD_HOST_EXECUTABLE)
+
+endif
diff --git a/libs/usb/tests/accessorytest/accessory.c b/libs/usb/tests/accessorytest/accessory.c
new file mode 100644
index 0000000..a3c47af
--- /dev/null
+++ b/libs/usb/tests/accessorytest/accessory.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "accessory.h"
+
+static void usage(char* name) {
+    fprintf(stderr, "Usage: %s [-a] [-h] [-ic input card] [-id input device] "
+                    "[-oc output card] [-d output device] [-a] [-h] [-i]\n\n"
+                    "\t-ic, -id, -oc and -od specify ALSA card and device numbers\n"
+                    "\t-a : enables AccessoryChat mode\n"
+                    "\t-i : enables HID pass through (requires running as root\n"
+                    "\t-h : prints this usage message\n", name);
+}
+
+int main(int argc, char* argv[])
+{
+    unsigned int input_card = 2;
+    unsigned int input_device = 0;
+    unsigned int output_card = 0;
+    unsigned int output_device = 0;
+    unsigned int enable_accessory = 0;
+    unsigned int enable_hid = 0;
+
+    /* parse command line arguments */
+    argv += 1;
+    while (*argv) {
+        if (strcmp(*argv, "-ic") == 0) {
+            argv++;
+            if (*argv)
+                input_card = atoi(*argv);
+        } else if (strcmp(*argv, "-id") == 0) {
+            argv++;
+            if (*argv)
+                input_device = atoi(*argv);
+        } else if (strcmp(*argv, "-oc") == 0) {
+            argv++;
+            if (*argv)
+                output_card = atoi(*argv);
+        } else if (strcmp(*argv, "-od") == 0) {
+            argv++;
+            if (*argv)
+                output_device = atoi(*argv);
+        } else if (strcmp(*argv, "-a") == 0) {
+            enable_accessory = 1;
+        } else if (strcmp(*argv, "-h") == 0) {
+            usage(argv[0]);
+            return 1;
+        } else if (strcmp(*argv, "-i") == 0) {
+           enable_hid = 1;
+        }
+        if (*argv)
+            argv++;
+    }
+
+    init_audio(input_card, input_device, output_card, output_device);
+    if (enable_hid)
+        init_hid();
+    usb_run(enable_accessory);
+
+    return 0;
+}
diff --git a/core/java/android/hardware/hdmi/HdmiCecDeviceInfo.aidl b/libs/usb/tests/accessorytest/accessory.h
similarity index 63%
copy from core/java/android/hardware/hdmi/HdmiCecDeviceInfo.aidl
copy to libs/usb/tests/accessorytest/accessory.h
index 1615910..55c4550 100644
--- a/core/java/android/hardware/hdmi/HdmiCecDeviceInfo.aidl
+++ b/libs/usb/tests/accessorytest/accessory.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,6 +14,13 @@
  * limitations under the License.
  */
 
-package android.hardware.hdmi;
+#ifndef __ACCESSORY_H__
+#define __ACCESSORY_H__
 
-parcelable HdmiCecDeviceInfo;
+int init_audio(unsigned int ic, unsigned int id, unsigned int oc, unsigned int od);
+void init_hid();
+void usb_run(int enable_accessory);
+
+struct usb_device* usb_wait_for_device();
+
+#endif /* __ACCESSORY_H__ */
diff --git a/libs/usb/tests/accessorytest/audio.c b/libs/usb/tests/accessorytest/audio.c
new file mode 100644
index 0000000..d23d9b3
--- /dev/null
+++ b/libs/usb/tests/accessorytest/audio.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <signal.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <errno.h>
+#include <string.h>
+
+#include <tinyalsa/asoundlib.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include "accessory.h"
+
+#define BUFFER_COUNT 2
+#define BUFFER_SIZE 16384
+
+#define BUFFER_EMPTY 0
+#define BUFFER_BUSY 1
+#define BUFFER_FULL 2
+
+static char* buffers[BUFFER_COUNT];
+static int buffer_states[BUFFER_COUNT];
+static int empty_index = 0;
+static int full_index = -1;
+
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t empty_cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t full_cond = PTHREAD_COND_INITIALIZER;
+
+static unsigned int input_card;
+static unsigned int input_device;
+
+static int get_empty()
+{
+    int index, other;
+
+    pthread_mutex_lock(&mutex);
+
+    while (empty_index == -1)
+        pthread_cond_wait(&empty_cond, &mutex);
+
+    index = empty_index;
+    other = (index == 0 ? 1 : 0);
+    buffer_states[index] = BUFFER_BUSY;
+    if (buffer_states[other] == BUFFER_EMPTY)
+        empty_index = other;
+    else
+        empty_index = -1;
+
+    pthread_mutex_unlock(&mutex);
+    return index;
+}
+
+static void put_empty(int index)
+{
+    pthread_mutex_lock(&mutex);
+
+    buffer_states[index] = BUFFER_EMPTY;
+    if (empty_index == -1) {
+        empty_index = index;
+        pthread_cond_signal(&empty_cond);
+    }
+
+    pthread_mutex_unlock(&mutex);
+}
+
+static int get_full()
+{
+    int index, other;
+
+    pthread_mutex_lock(&mutex);
+
+    while (full_index == -1)
+        pthread_cond_wait(&full_cond, &mutex);
+
+    index = full_index;
+    other = (index == 0 ? 1 : 0);
+    buffer_states[index] = BUFFER_BUSY;
+    if (buffer_states[other] == BUFFER_FULL)
+        full_index = other;
+    else
+        full_index = -1;
+
+    pthread_mutex_unlock(&mutex);
+    return index;
+}
+
+static void put_full(int index)
+{
+    pthread_mutex_lock(&mutex);
+
+    buffer_states[index] = BUFFER_FULL;
+    if (full_index == -1) {
+        full_index = index;
+        pthread_cond_signal(&full_cond);
+    }
+
+    pthread_mutex_unlock(&mutex);
+}
+
+static void* capture_thread(void* arg)
+{
+    struct pcm_config config;
+    struct pcm *pcm = NULL;
+
+    fprintf(stderr, "capture_thread start\n");
+
+    memset(&config, 0, sizeof(config));
+
+    config.channels = 2;
+    config.rate = 44100;
+    config.period_size = 1024;
+    config.period_count = 4;
+    config.format = PCM_FORMAT_S16_LE;
+
+    while (1) {
+        while (!pcm) {
+            pcm = pcm_open(input_card, input_device, PCM_IN, &config);
+            if (pcm && !pcm_is_ready(pcm)) {
+                pcm_close(pcm);
+                pcm = NULL;
+            }
+            if (!pcm)
+                sleep(1);
+        }
+
+        while (pcm) {
+            int index = get_empty();
+            if (pcm_read(pcm, buffers[index], BUFFER_SIZE)) {
+                put_empty(index);
+                pcm_close(pcm);
+                pcm = NULL;
+            } else {
+                put_full(index);
+            }
+        }
+    }
+
+    fprintf(stderr, "capture_thread done\n");
+    return NULL;
+}
+
+static void* play_thread(void* arg)
+{
+    struct pcm *pcm = arg;
+    char *buffer;
+    int index, err;
+
+    fprintf(stderr, "play_thread start\n");
+
+    while (1) {
+        index = get_full();
+
+        err = pcm_write(pcm, buffers[index], BUFFER_SIZE);
+        if (err)
+            fprintf(stderr, "pcm_write err: %d\n", err);
+
+        put_empty(index);
+    }
+
+    fprintf(stderr, "play_thread done\n");
+    pcm_close(pcm);
+    free(buffer);
+
+    return NULL;
+}
+
+int init_audio(unsigned int ic, unsigned int id, unsigned int oc, unsigned int od)
+{
+    pthread_t tid;
+    struct pcm_config config;
+    struct pcm *pcm;
+    int i;
+
+    input_card = ic;
+    input_device = id;
+
+    for (i = 0; i < BUFFER_COUNT; i++) {
+        buffers[i] = malloc(BUFFER_SIZE);
+        buffer_states[i] = BUFFER_EMPTY;
+    }
+
+    memset(&config, 0, sizeof(config));
+    config.channels = 2;
+    config.rate = 44100;
+    config.period_size = 1024;
+    config.period_count = 4;
+    config.format = PCM_FORMAT_S16_LE;
+
+    pcm = pcm_open(oc, od, PCM_OUT, &config);
+    if (!pcm || !pcm_is_ready(pcm)) {
+        fprintf(stderr, "Unable to open PCM device %d/%d for output (%s)\n",
+               oc, od, pcm_get_error(pcm));
+        return -1;
+    }
+
+    pthread_create(&tid, NULL, capture_thread, NULL);
+    pthread_create(&tid, NULL, play_thread, pcm);
+    return 0;
+}
diff --git a/libs/usb/tests/accessorytest/f_accessory.h b/libs/usb/tests/accessorytest/f_accessory.h
new file mode 100644
index 0000000..312f4ba
--- /dev/null
+++ b/libs/usb/tests/accessorytest/f_accessory.h
@@ -0,0 +1,148 @@
+/*
+ * Gadget Function Driver for Android USB accessories
+ *
+ * Copyright (C) 2011 Google, Inc.
+ * Author: Mike Lockwood <lockwood@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __LINUX_USB_F_ACCESSORY_H
+#define __LINUX_USB_F_ACCESSORY_H
+
+/* Use Google Vendor ID when in accessory mode */
+#define USB_ACCESSORY_VENDOR_ID 0x18D1
+
+
+/* Product ID to use when in accessory mode */
+#define USB_ACCESSORY_PRODUCT_ID 0x2D00
+
+/* Product ID to use when in accessory mode and adb is enabled */
+#define USB_ACCESSORY_ADB_PRODUCT_ID 0x2D01
+
+/* Indexes for strings sent by the host via ACCESSORY_SEND_STRING */
+#define ACCESSORY_STRING_MANUFACTURER   0
+#define ACCESSORY_STRING_MODEL          1
+#define ACCESSORY_STRING_DESCRIPTION    2
+#define ACCESSORY_STRING_VERSION        3
+#define ACCESSORY_STRING_URI            4
+#define ACCESSORY_STRING_SERIAL         5
+
+/* Control request for retrieving device's protocol version
+ *
+ *	requestType:    USB_DIR_IN | USB_TYPE_VENDOR
+ *	request:        ACCESSORY_GET_PROTOCOL
+ *	value:          0
+ *	index:          0
+ *	data            version number (16 bits little endian)
+ *                    1 for original accessory support
+ *                    2 adds audio and HID support
+ */
+#define ACCESSORY_GET_PROTOCOL  51
+
+/* Control request for host to send a string to the device
+ *
+ *	requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
+ *	request:        ACCESSORY_SEND_STRING
+ *	value:          0
+ *	index:          string ID
+ *	data            zero terminated UTF8 string
+ *
+ *  The device can later retrieve these strings via the
+ *  ACCESSORY_GET_STRING_* ioctls
+ */
+#define ACCESSORY_SEND_STRING   52
+
+/* Control request for starting device in accessory mode.
+ * The host sends this after setting all its strings to the device.
+ *
+ *	requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
+ *	request:        ACCESSORY_START
+ *	value:          0
+ *	index:          0
+ *	data            none
+ */
+#define ACCESSORY_START         53
+
+/* Control request for registering a HID device.
+ * Upon registering, a unique ID is sent by the accessory in the
+ * value parameter. This ID will be used for future commands for
+ * the device
+ *
+ *	requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
+ *	request:        ACCESSORY_REGISTER_HID_DEVICE
+ *	value:          Accessory assigned ID for the HID device
+ *	index:          total length of the HID report descriptor
+ *	data            none
+ */
+#define ACCESSORY_REGISTER_HID         54
+
+/* Control request for unregistering a HID device.
+ *
+ *	requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
+ *	request:        ACCESSORY_REGISTER_HID
+ *	value:          Accessory assigned ID for the HID device
+ *	index:          0
+ *	data            none
+ */
+#define ACCESSORY_UNREGISTER_HID         55
+
+/* Control request for sending the HID report descriptor.
+ * If the HID descriptor is longer than the endpoint zero max packet size,
+ * the descriptor will be sent in multiple ACCESSORY_SET_HID_REPORT_DESC
+ * commands. The data for the descriptor must be sent sequentially
+ * if multiple packets are needed.
+ *
+ *	requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
+ *	request:        ACCESSORY_SET_HID_REPORT_DESC
+ *	value:          Accessory assigned ID for the HID device
+ *	index:          offset of data in descriptor
+ *                  (needed when HID descriptor is too big for one packet)
+ *	data            the HID report descriptor
+ */
+#define ACCESSORY_SET_HID_REPORT_DESC         56
+
+/* Control request for sending HID events.
+ *
+ *	requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
+ *	request:        ACCESSORY_SEND_HID_EVENT
+ *	value:          Accessory assigned ID for the HID device
+ *	index:          0
+ *	data            the HID report for the event
+ */
+#define ACCESSORY_SEND_HID_EVENT         57
+
+/* Control request for setting the audio mode.
+ *
+ *	requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
+ *	request:        ACCESSORY_SET_AUDIO_MODE
+ *	value:          0 - no audio
+ *                  1 - device to host, 44100 16-bit stereo PCM
+ *	index:          0
+ *	data            the HID report for the event
+ */
+#define ACCESSORY_SET_AUDIO_MODE         58
+
+
+
+/* ioctls for retrieving strings set by the host */
+#define ACCESSORY_GET_STRING_MANUFACTURER   _IOW('M', 1, char[256])
+#define ACCESSORY_GET_STRING_MODEL          _IOW('M', 2, char[256])
+#define ACCESSORY_GET_STRING_DESCRIPTION    _IOW('M', 3, char[256])
+#define ACCESSORY_GET_STRING_VERSION        _IOW('M', 4, char[256])
+#define ACCESSORY_GET_STRING_URI            _IOW('M', 5, char[256])
+#define ACCESSORY_GET_STRING_SERIAL         _IOW('M', 6, char[256])
+/* returns 1 if there is a start request pending */
+#define ACCESSORY_IS_START_REQUESTED        _IO('M', 7)
+/* returns audio mode (set via the ACCESSORY_SET_AUDIO_MODE control request) */
+#define ACCESSORY_GET_AUDIO_MODE            _IO('M', 8)
+
+#endif /* __LINUX_USB_F_ACCESSORY_H */
diff --git a/libs/usb/tests/accessorytest/hid.c b/libs/usb/tests/accessorytest/hid.c
new file mode 100644
index 0000000..b70d678
--- /dev/null
+++ b/libs/usb/tests/accessorytest/hid.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <pthread.h>
+#include <time.h>
+
+#include <sys/inotify.h>
+#include <linux/hidraw.h>
+#include <usbhost/usbhost.h>
+
+#include "f_accessory.h"
+#include "accessory.h"
+
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static int next_id = 1;
+
+static void milli_sleep(int millis) {
+    struct timespec tm;
+
+    tm.tv_sec = 0;
+    tm.tv_nsec = millis * 1000000;
+    nanosleep(&tm, NULL);
+}
+
+static void* hid_thread(void* arg) {
+    int fd = (int)arg;
+    char buffer[4096];
+    int id, ret, offset;
+    struct usb_device *device;
+    struct usb_device_descriptor *device_desc;
+    int max_packet;
+    struct hidraw_report_descriptor desc;
+    int desc_length;
+
+    fprintf(stderr, "hid_thread start fd: %d\n", fd);
+
+    if (ioctl(fd, HIDIOCGRDESCSIZE, &desc_length)) {
+        fprintf(stderr, "HIDIOCGRDESCSIZE failed\n");
+        close(fd);
+        goto err;
+    }
+
+    desc.size = HID_MAX_DESCRIPTOR_SIZE - 1;
+    if (ioctl(fd, HIDIOCGRDESC, &desc)) {
+        fprintf(stderr, "HIDIOCGRDESC failed\n");
+        close(fd);
+        goto err;
+    }
+
+wait_for_device:
+    fprintf(stderr, "waiting for device fd: %d\n", fd);
+    device = usb_wait_for_device();
+    max_packet = usb_device_get_device_descriptor(device)->bMaxPacketSize0;
+    // FIXME
+    max_packet--;
+
+    // FIXME
+    milli_sleep(500);
+
+    pthread_mutex_lock(&mutex);
+    id = next_id++;
+
+    ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
+            ACCESSORY_REGISTER_HID, id, desc_length, NULL, 0, 1000);
+    fprintf(stderr, "ACCESSORY_REGISTER_HID returned %d\n", ret);
+
+    // FIXME
+    milli_sleep(500);
+
+    for (offset = 0; offset < desc_length; ) {
+        int count = desc_length - offset;
+        if (count > max_packet) count = max_packet;
+
+    fprintf(stderr, "sending ACCESSORY_SET_HID_REPORT_DESC offset: %d count: %d desc_length: %d\n",
+            offset, count, desc_length);
+        ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
+                ACCESSORY_SET_HID_REPORT_DESC, id, offset, &desc.value[offset], count, 1000);
+    fprintf(stderr, "ACCESSORY_SET_HID_REPORT_DESC returned %d errno %d\n", ret, errno);
+        offset += count;
+    }
+
+    pthread_mutex_unlock(&mutex);
+
+    while (1) {
+        ret = read(fd, buffer, sizeof(buffer));
+        if (ret < 0) {
+fprintf(stderr, "read failed, errno: %d, fd: %d\n", errno, fd);
+            break;
+        }
+
+        ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
+                    ACCESSORY_SEND_HID_EVENT, id, 0, buffer, ret, 1000);
+        if (ret < 0 && errno != EPIPE) {
+fprintf(stderr, "ACCESSORY_SEND_HID_EVENT returned %d errno: %d\n", ret, errno);
+            goto wait_for_device;
+        }
+    }
+
+fprintf(stderr, "ACCESSORY_UNREGISTER_HID\n");
+    ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
+            ACCESSORY_UNREGISTER_HID, id, 0, NULL, 0, 1000);
+
+fprintf(stderr, "hid thread exiting\n");
+err:
+    return NULL;
+}
+
+static void open_hid(const char* name)
+{
+    char path[100];
+
+    snprintf(path, sizeof(path), "/dev/%s", name);
+    int fd = open(path, O_RDWR);
+    if (fd < 0) return;
+
+    fprintf(stderr, "opened /dev/%s\n", name);
+    pthread_t th;
+    pthread_create(&th, NULL, hid_thread, (void *)fd);
+}
+
+static void* inotify_thread(void* arg)
+{
+    open_hid("hidraw0");
+    open_hid("hidraw1");
+    open_hid("hidraw2");
+    open_hid("hidraw3");
+    open_hid("hidraw4");
+    open_hid("hidraw5");
+    open_hid("hidraw6");
+    open_hid("hidraw7");
+    open_hid("hidraw8");
+    open_hid("hidraw9");
+
+    int inotify_fd = inotify_init();
+    inotify_add_watch(inotify_fd, "/dev", IN_DELETE | IN_CREATE);
+
+    while (1) {
+        char event_buf[512];
+        struct inotify_event *event;
+        int event_pos = 0;
+        int event_size;
+
+        int count = read(inotify_fd, event_buf, sizeof(event_buf));
+        if (count < (int)sizeof(*event)) {
+            if(errno == EINTR)
+                continue;
+            fprintf(stderr, "could not get event, %s\n", strerror(errno));
+            break;
+        }
+        while (count >= (int)sizeof(*event)) {
+            event = (struct inotify_event *)(event_buf + event_pos);
+            //fprintf(stderr, "%d: %08x \"%s\"\n", event->wd, event->mask,
+            //        event->len ? event->name : "");
+            if (event->len) {
+                if(event->mask & IN_CREATE) {
+                    fprintf(stderr, "created %s\n", event->name);
+                    // FIXME
+                    milli_sleep(50);
+                    open_hid(event->name);
+                } else {
+                    fprintf(stderr, "lost %s\n", event->name);
+                }
+            }
+            event_size = sizeof(*event) + event->len;
+            count -= event_size;
+            event_pos += event_size;
+        }
+    }
+
+    close(inotify_fd);
+    return NULL;
+}
+
+void init_hid()
+{
+    pthread_t th;
+    pthread_create(&th, NULL, inotify_thread, NULL);
+}
diff --git a/libs/usb/tests/accessorytest/usb.c b/libs/usb/tests/accessorytest/usb.c
new file mode 100644
index 0000000..ac72b35
--- /dev/null
+++ b/libs/usb/tests/accessorytest/usb.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <signal.h>
+#include <pthread.h>
+#include <errno.h>
+#include <string.h>
+
+#include <usbhost/usbhost.h>
+#include "f_accessory.h"
+
+#include "accessory.h"
+
+static struct usb_device *current_device = NULL;
+static uint8_t read_ep;
+static uint8_t write_ep;
+
+static pthread_mutex_t device_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t device_cond = PTHREAD_COND_INITIALIZER;
+
+static void milli_sleep(int millis) {
+    struct timespec tm;
+
+    tm.tv_sec = 0;
+    tm.tv_nsec = millis * 1000000;
+    nanosleep(&tm, NULL);
+}
+
+static void* read_thread(void* arg) {
+    int ret = 0;
+
+    while (current_device && ret >= 0) {
+        char    buffer[16384];
+
+        ret = usb_device_bulk_transfer(current_device, read_ep, buffer, sizeof(buffer), 1000);
+        if (ret < 0 && errno == ETIMEDOUT)
+            ret = 0;
+        if (ret > 0) {
+            fwrite(buffer, 1, ret, stdout);
+            fprintf(stderr, "\n");
+            fflush(stdout);
+        }
+    }
+
+    return NULL;
+}
+
+static void* write_thread(void* arg) {
+    int ret = 0;
+
+    while (ret >= 0) {
+        char    buffer[16384];
+        char *line = fgets(buffer, sizeof(buffer), stdin);
+        if (!line || !current_device)
+            break;
+        ret = usb_device_bulk_transfer(current_device, write_ep, line, strlen(line), 1000);
+    }
+
+    return NULL;
+}
+
+static void send_string(struct usb_device *device, int index, const char* string) {
+    usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
+            ACCESSORY_SEND_STRING, 0, index, (void *)string, strlen(string) + 1, 0);
+
+    // some devices can't handle back-to-back requests, so delay a bit
+    milli_sleep(10);
+}
+
+static int usb_device_added(const char *devname, void* client_data) {
+    uint16_t vendorId, productId;
+    int ret;
+    int enable_accessory = (int)client_data;
+
+    struct usb_device *device = usb_device_open(devname);
+    if (!device) {
+        fprintf(stderr, "usb_device_open failed\n");
+        return 0;
+    }
+
+    vendorId = usb_device_get_vendor_id(device);
+    productId = usb_device_get_product_id(device);
+
+    if (!current_device && vendorId == 0x18D1 && productId >= 0x2D00 && productId <= 0x2D05) {
+
+        pthread_mutex_lock(&device_mutex);
+        fprintf(stderr, "Found android device in accessory mode\n");
+        current_device = device;
+        pthread_cond_broadcast(&device_cond);
+        pthread_mutex_unlock(&device_mutex);
+
+        if (enable_accessory) {
+            struct usb_descriptor_header* desc;
+            struct usb_descriptor_iter iter;
+            struct usb_interface_descriptor *intf = NULL;
+            struct usb_endpoint_descriptor *ep1 = NULL;
+            struct usb_endpoint_descriptor *ep2 = NULL;
+            pthread_t th;
+
+            usb_descriptor_iter_init(device, &iter);
+            while ((desc = usb_descriptor_iter_next(&iter)) != NULL && (!intf || !ep1 || !ep2)) {
+                if (desc->bDescriptorType == USB_DT_INTERFACE) {
+                    intf = (struct usb_interface_descriptor *)desc;
+                } else if (desc->bDescriptorType == USB_DT_ENDPOINT) {
+                    if (ep1)
+                        ep2 = (struct usb_endpoint_descriptor *)desc;
+                    else
+                        ep1 = (struct usb_endpoint_descriptor *)desc;
+                }
+            }
+
+            if (!intf) {
+                fprintf(stderr, "interface not found\n");
+                exit(1);
+            }
+            if (!ep1 || !ep2) {
+                fprintf(stderr, "endpoints not found\n");
+                exit(1);
+            }
+
+            if (usb_device_claim_interface(device, intf->bInterfaceNumber)) {
+                fprintf(stderr, "usb_device_claim_interface failed errno: %d\n", errno);
+                exit(1);
+            }
+
+            if ((ep1->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
+                read_ep = ep1->bEndpointAddress;
+                write_ep = ep2->bEndpointAddress;
+            } else {
+                read_ep = ep2->bEndpointAddress;
+                write_ep = ep1->bEndpointAddress;
+            }
+
+            pthread_create(&th, NULL, read_thread, NULL);
+            pthread_create(&th, NULL, write_thread, NULL);
+        }
+    } else {
+//        fprintf(stderr, "Found new device - attempting to switch to accessory mode\n");
+
+        uint16_t protocol = -1;
+        ret = usb_device_control_transfer(device, USB_DIR_IN | USB_TYPE_VENDOR,
+                ACCESSORY_GET_PROTOCOL, 0, 0, &protocol, sizeof(protocol), 1000);
+        if (ret < 0) {
+ //           fprintf(stderr, "ACCESSORY_GET_PROTOCOL returned %d errno: %d\n", ret, errno);
+        } else {
+            fprintf(stderr, "device supports protocol version %d\n", protocol);
+            if (protocol >= 2) {
+                if (enable_accessory) {
+                    send_string(device, ACCESSORY_STRING_MANUFACTURER, "Google, Inc.");
+                    send_string(device, ACCESSORY_STRING_MODEL, "AccessoryChat");
+                    send_string(device, ACCESSORY_STRING_DESCRIPTION, "Accessory Chat");
+                    send_string(device, ACCESSORY_STRING_VERSION, "1.0");
+                    send_string(device, ACCESSORY_STRING_URI, "http://www.android.com");
+                    send_string(device, ACCESSORY_STRING_SERIAL, "1234567890");
+                }
+
+                fprintf(stderr, "sending ACCESSORY_SET_AUDIO_MODE\n");
+                ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
+                        ACCESSORY_SET_AUDIO_MODE, 1, 0, NULL, 0, 1000);
+                if (ret < 0)
+                    fprintf(stderr, "ACCESSORY_SET_AUDIO_MODE returned %d errno: %d\n", ret, errno);
+
+                fprintf(stderr, "sending ACCESSORY_START\n");
+                ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
+                        ACCESSORY_START, 0, 0, NULL, 0, 1000);
+                fprintf(stderr, "did ACCESSORY_START\n");
+                if (ret < 0)
+                    fprintf(stderr, "ACCESSORY_START returned %d errno: %d\n", ret, errno);
+            }
+        }
+
+        return 0;
+    }
+
+    if (device != current_device)
+        usb_device_close(device);
+
+    return 0;
+}
+
+static int usb_device_removed(const char *devname, void* client_data) {
+    pthread_mutex_lock(&device_mutex);
+
+    if (current_device && !strcmp(usb_device_get_name(current_device), devname)) {
+        fprintf(stderr, "current device disconnected\n");
+        usb_device_close(current_device);
+        current_device = NULL;
+    }
+
+    pthread_mutex_unlock(&device_mutex);
+    return 0;
+}
+
+struct usb_device* usb_wait_for_device() {
+    struct usb_device* device = NULL;
+
+    pthread_mutex_lock(&device_mutex);
+    while (!current_device)
+         pthread_cond_wait(&device_cond, &device_mutex);
+    device = current_device;
+    pthread_mutex_unlock(&device_mutex);
+
+    return device;
+}
+
+void usb_run(int enable_accessory) {
+    struct usb_host_context* context = usb_host_init();
+
+    usb_host_run(context, usb_device_added, usb_device_removed, NULL, (void *)enable_accessory);
+}
+
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index 099cd3f..ce9a742 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.text.TextUtils;
 import android.util.Log;
 
 import java.lang.annotation.Retention;
@@ -26,6 +27,7 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -150,6 +152,12 @@
      */
     public final static int FLAG_SCO = 0x1 << 2;
 
+    /**
+     * @hide
+     * CANDIDATE FOR PUBLIC API
+     * Flag requesting the use of an output stream supporting hardware A/V synchronization.
+     */
+    public final static int FLAG_HW_AV_SYNC = 0x1 << 4;
 
     private int mUsage = USAGE_UNKNOWN;
     private int mContentType = CONTENT_TYPE_UNKNOWN;
@@ -194,7 +202,7 @@
      */
     public int getFlags() {
         // only return the flags that are public
-        return (mFlags & (FLAG_AUDIBILITY_ENFORCED));
+        return (mFlags & (FLAG_AUDIBILITY_ENFORCED | FLAG_HW_AV_SYNC));
     }
 
     /**
@@ -257,12 +265,7 @@
             aa.mSource = mSource;
             aa.mFlags = mFlags;
             aa.mTags = (HashSet<String>) mTags.clone();
-            final Iterator<String> tagIterator = mTags.iterator();
-            String allTagsInOne = new String();
-            while (tagIterator.hasNext()) {
-                allTagsInOne += tagIterator.next() + ";";
-            }
-            aa.mFormattedTags = allTagsInOne;
+            aa.mFormattedTags = TextUtils.join(";", mTags);
             return aa;
         }
 
@@ -343,7 +346,7 @@
          */
         public Builder setFlags(int flags) {
             flags &= (AudioAttributes.FLAG_AUDIBILITY_ENFORCED | AudioAttributes.FLAG_SCO
-                    | AudioAttributes.FLAG_SECURE);
+                    | AudioAttributes.FLAG_SECURE | AudioAttributes.FLAG_HW_AV_SYNC);
             mFlags |= flags;
             return this;
         }
@@ -503,12 +506,14 @@
         boolean hasFlattenedTags = ((in.readInt() & FLATTEN_TAGS) == FLATTEN_TAGS);
         mTags = new HashSet<String>();
         if (hasFlattenedTags) {
-            mTags.add(in.readString());
+            mFormattedTags = new String(in.readString());
+            mTags.add(mFormattedTags);
         } else {
             String[] tagsArray = in.readStringArray();
             for (int i = tagsArray.length - 1 ; i >= 0 ; i--) {
                 mTags.add(tagsArray[i]);
             }
+            mFormattedTags = TextUtils.join(";", mTags);
         }
     }
 
@@ -528,14 +533,33 @@
         }
     };
 
-    /** @hide */
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        AudioAttributes that = (AudioAttributes) o;
+
+        return ((mContentType == that.mContentType)
+                && (mFlags == that.mFlags)
+                && (mSource == that.mSource)
+                && (mUsage == that.mUsage)
+                //mFormattedTags is never null due to assignment in Builder or unmarshalling
+                && (mFormattedTags.equals(that.mFormattedTags)));
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mContentType, mFlags, mSource, mUsage, mFormattedTags);
+    }
+
     @Override
     public String toString () {
         return new String("AudioAttributes:"
                 + " usage=" + mUsage
                 + " content=" + mContentType
                 + " flags=0x" + Integer.toHexString(mFlags).toUpperCase()
-                + " tags=" + mTags);
+                + " tags=" + mFormattedTags);
     }
 
     /** @hide */
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index 2a612e8..d93d81b 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -249,6 +249,20 @@
     private AudioFormat(int ignoredArgument) {
     }
 
+    /**
+     * Constructor used by the JNI
+     */
+    // Update sound trigger JNI in core/jni/android_hardware_SoundTrigger.cpp when modifying this
+    // constructor
+    private AudioFormat(int encoding, int sampleRate, int channelMask) {
+        mEncoding = encoding;
+        mSampleRate = sampleRate;
+        mChannelMask = channelMask;
+        mPropertySetMask = AUDIO_FORMAT_HAS_PROPERTY_ENCODING |
+                AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE |
+                AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK;
+    }
+
     /** @hide */
     public final static int AUDIO_FORMAT_HAS_PROPERTY_NONE = 0x0;
     /** @hide */
@@ -263,18 +277,39 @@
     private int mChannelMask;
     private int mPropertySetMask;
 
-    /** @hide */
+    /**
+     * Return the encoding.
+     * @return one of the values that can be set in {@link Builder#setEncoding(int)} or
+     * {@link AudioFormat#ENCODING_INVALID} if not set.
+     */
     public int getEncoding() {
+        if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_ENCODING) == 0) {
+            return ENCODING_INVALID;
+        }
         return mEncoding;
     }
 
-    /** @hide */
+    /**
+     * Return the sample rate.
+     * @return one of the values that can be set in {@link Builder#setSampleRate(int)} or
+     * 0 if not set.
+     */
     public int getSampleRate() {
+        if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE) == 0) {
+            return 0;
+        }
         return mSampleRate;
     }
 
-    /** @hide */
+    /**
+     * Return the channel mask.
+     * @return one of the values that can be set in {@link Builder#setChannelMask(int)} or
+     * {@link AudioFormat#CHANNEL_INVALID} if not set.
+     */
     public int getChannelMask() {
+        if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK) == 0) {
+            return CHANNEL_INVALID;
+        }
         return mChannelMask;
     }
 
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index ac63ea6..bd50142 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -834,6 +834,7 @@
     /**
      * Get the stream type whose volume is driving the UI sounds volume.
      * UI sounds are screen lock/unlock, camera shutter, key clicks...
+     * It is assumed that this stream type is also tied to ringer mode changes.
      * @hide
      */
     public int getMasterStreamType() {
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index e1c6e75..705d9c0 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -291,14 +291,14 @@
     };
     private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] {
         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
-        AudioSystem.STREAM_MUSIC,           // STREAM_SYSTEM
+        AudioSystem.STREAM_RING,            // STREAM_SYSTEM
         AudioSystem.STREAM_RING,            // STREAM_RING
         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
         AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
-        AudioSystem.STREAM_MUSIC,           // STREAM_SYSTEM_ENFORCED
-        AudioSystem.STREAM_MUSIC,           // STREAM_DTMF
+        AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
+        AudioSystem.STREAM_RING,            // STREAM_DTMF
         AudioSystem.STREAM_MUSIC            // STREAM_TTS
     };
     private int[] mStreamVolumeAlias;
@@ -1572,15 +1572,7 @@
 
     /** @see AudioManager#getMasterStreamType()  */
     public int getMasterStreamType() {
-        switch (mPlatformType) {
-            case PLATFORM_VOICE:
-                return AudioSystem.STREAM_RING;
-            case PLATFORM_TELEVISION:
-                return AudioSystem.STREAM_MUSIC;
-            default:
-                break;
-        }
-        return AudioSystem.STREAM_NOTIFICATION;
+        return mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
     }
 
     /** @see AudioManager#setMicrophoneMute(boolean) */
@@ -4340,7 +4332,7 @@
             AudioSystem.DEVICE_OUT_WIRED_HEADSET | AudioSystem.DEVICE_OUT_WIRED_HEADPHONE |
             AudioSystem.DEVICE_OUT_ALL_A2DP | AudioSystem.DEVICE_OUT_HDMI |
             AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET | AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET |
-            AudioSystem.DEVICE_OUT_ALL_USB;
+            AudioSystem.DEVICE_OUT_ALL_USB | AudioSystem.DEVICE_OUT_LINE;
 
     // must be called before removing the device from mConnectedDevices
     private int checkSendBecomingNoisyIntent(int device, int state) {
@@ -4386,7 +4378,9 @@
             connType = AudioRoutesInfo.MAIN_HEADSET;
             intent.setAction(Intent.ACTION_HEADSET_PLUG);
             intent.putExtra("microphone", 1);
-        } else if (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) {
+        } else if (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE ||
+                   device == AudioSystem.DEVICE_OUT_LINE) {
+            /*do apps care about line-out vs headphones?*/
             connType = AudioRoutesInfo.MAIN_HEADPHONES;
             intent.setAction(Intent.ACTION_HEADSET_PLUG);
             intent.putExtra("microphone", 0);
@@ -4429,7 +4423,8 @@
     {
         synchronized (mConnectedDevices) {
             if ((state == 0) && ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) ||
-                    (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE))) {
+                    (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) ||
+                    (device == AudioSystem.DEVICE_OUT_LINE))) {
                 setBluetoothA2dpOnInt(true);
             }
             boolean isUsb = ((device & ~AudioSystem.DEVICE_OUT_ALL_USB) == 0) ||
@@ -4438,7 +4433,8 @@
             handleDeviceConnection((state == 1), device, (isUsb ? name : ""));
             if (state != 0) {
                 if ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) ||
-                    (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE)) {
+                    (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) ||
+                    (device == AudioSystem.DEVICE_OUT_LINE)) {
                     setBluetoothA2dpOnInt(false);
                 }
                 if ((device & mSafeMediaVolumeDevices) != 0) {
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 8e2ca95..e11aab1 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -487,5 +487,10 @@
     public static native int releaseAudioPatch(AudioPatch patch);
     public static native int listAudioPatches(ArrayList<AudioPatch> patches, int[] generation);
     public static native int setAudioPortConfig(AudioPortConfig config);
+
+    // must be kept in sync with value in include/system/audio.h
+    public static final int AUDIO_HW_SYNC_INVALID = 0;
+
+    public static native int getAudioHwSyncForSession(int sessionId);
 }
 
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 25f10d2..ca707d8 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -20,6 +20,7 @@
 import java.util.UUID;
 import java.util.HashMap;
 import java.util.List;
+import android.annotation.SystemApi;
 import android.os.Binder;
 import android.os.Debug;
 import android.os.Handler;
@@ -521,6 +522,18 @@
             throws DeniedByServerException;
 
     /**
+     * Remove provisioning from a device.  Only system apps may unprovision a
+     * device.  Note that removing provisioning will invalidate any keys saved
+     * for offline use (KEY_TYPE_OFFLINE), which may render downloaded content
+     * unplayable until new licenses are acquired.  Since provisioning is global
+     * to the device, license invalidation will apply to all content downloaded
+     * by any app, so appropriate warnings should be given to the user.
+     * @hide
+     */
+    @SystemApi
+    public native void unprovisionDevice();
+
+    /**
      * A means of enforcing limits on the number of concurrent streams per subscriber
      * across devices is provided via SecureStop. This is achieved by securely
      * monitoring the lifetime of sessions.
diff --git a/media/java/android/media/MediaMetadata.java b/media/java/android/media/MediaMetadata.java
index 3f7ebce..bbf6a3b 100644
--- a/media/java/android/media/MediaMetadata.java
+++ b/media/java/android/media/MediaMetadata.java
@@ -15,10 +15,14 @@
  */
 package android.media;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.graphics.Bitmap;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.text.TextUtils;
 import android.text.format.Time;
 import android.util.ArrayMap;
 import android.util.Log;
@@ -115,7 +119,7 @@
     public static final String METADATA_KEY_ART = "android.media.metadata.ART";
 
     /**
-     * The artwork for the media as a Uri style String.
+     * The artwork for the media as a Uri.
      */
     public static final String METADATA_KEY_ART_URI = "android.media.metadata.ART_URI";
 
@@ -126,8 +130,7 @@
     public static final String METADATA_KEY_ALBUM_ART = "android.media.metadata.ALBUM_ART";
 
     /**
-     * The artwork for the album of the media's original source as a Uri style
-     * String.
+     * The artwork for the album of the media's original source as a Uri.
      */
     public static final String METADATA_KEY_ALBUM_ART_URI = "android.media.metadata.ALBUM_ART_URI";
 
@@ -145,36 +148,104 @@
      */
     public static final String METADATA_KEY_RATING = "android.media.metadata.RATING";
 
+    /**
+     * A title that is suitable for display to the user. This will generally be
+     * the same as {@link #METADATA_KEY_TITLE} but may differ for some formats.
+     * When displaying media described by this metadata this should be preferred
+     * if present.
+     */
+    public static final String METADATA_KEY_DISPLAY_TITLE = "android.media.metadata.DISPLAY_TITLE";
+
+    /**
+     * A subtitle that is suitable for display to the user. When displaying a
+     * second line for media described by this metadata this should be preferred
+     * to other fields if present.
+     */
+    public static final String METADATA_KEY_DISPLAY_SUBTITLE
+            = "android.media.metadata.DISPLAY_SUBTITLE";
+
+    /**
+     * A description that is suitable for display to the user. When displaying
+     * more information for media described by this metadata this should be
+     * preferred to other fields if present.
+     */
+    public static final String METADATA_KEY_DISPLAY_DESCRIPTION
+            = "android.media.metadata.DISPLAY_DESCRIPTION";
+
+    /**
+     * An icon or thumbnail that is suitable for display to the user. When
+     * displaying an icon for media described by this metadata this should be
+     * preferred to other fields if present. This must be a {@link Bitmap}.
+     */
+    public static final String METADATA_KEY_DISPLAY_ICON
+            = "android.media.metadata.DISPLAY_ICON";
+
+    /**
+     * An icon or thumbnail that is suitable for display to the user. When
+     * displaying more information for media described by this metadata the
+     * display description should be preferred to other fields when present.
+     */
+    public static final String METADATA_KEY_DISPLAY_ICON_URI
+            = "android.media.metadata.DISPLAY_ICON_URI";
+
+    private static final String[] PREFERRED_DESCRIPTION_ORDER = {
+            METADATA_KEY_TITLE,
+            METADATA_KEY_ALBUM,
+            METADATA_KEY_ARTIST,
+            METADATA_KEY_ALBUM_ARTIST,
+            METADATA_KEY_WRITER,
+            METADATA_KEY_AUTHOR,
+            METADATA_KEY_COMPOSER
+    };
+
+    private static final String[] PREFERRED_BITMAP_ORDER = {
+            METADATA_KEY_DISPLAY_ICON,
+            METADATA_KEY_ART,
+            METADATA_KEY_ALBUM_ART
+    };
+
+    private static final String[] PREFERRED_URI_ORDER = {
+            METADATA_KEY_DISPLAY_ICON_URI,
+            METADATA_KEY_ART_URI,
+            METADATA_KEY_ALBUM_ART_URI
+    };
+
     private static final int METADATA_TYPE_INVALID = -1;
     private static final int METADATA_TYPE_LONG = 0;
-    private static final int METADATA_TYPE_STRING = 1;
+    private static final int METADATA_TYPE_TEXT = 1;
     private static final int METADATA_TYPE_BITMAP = 2;
     private static final int METADATA_TYPE_RATING = 3;
+    private static final int METADATA_TYPE_URI = 4;
     private static final ArrayMap<String, Integer> METADATA_KEYS_TYPE;
 
     static {
         METADATA_KEYS_TYPE = new ArrayMap<String, Integer>();
-        METADATA_KEYS_TYPE.put(METADATA_KEY_TITLE, METADATA_TYPE_STRING);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_ARTIST, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_TITLE, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ARTIST, METADATA_TYPE_TEXT);
         METADATA_KEYS_TYPE.put(METADATA_KEY_DURATION, METADATA_TYPE_LONG);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM, METADATA_TYPE_STRING);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_AUTHOR, METADATA_TYPE_STRING);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_WRITER, METADATA_TYPE_STRING);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_COMPOSER, METADATA_TYPE_STRING);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_COMPILATION, METADATA_TYPE_STRING);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_DATE, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_AUTHOR, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_WRITER, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_COMPOSER, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_COMPILATION, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DATE, METADATA_TYPE_TEXT);
         METADATA_KEYS_TYPE.put(METADATA_KEY_YEAR, METADATA_TYPE_LONG);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_GENRE, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_GENRE, METADATA_TYPE_TEXT);
         METADATA_KEYS_TYPE.put(METADATA_KEY_TRACK_NUMBER, METADATA_TYPE_LONG);
         METADATA_KEYS_TYPE.put(METADATA_KEY_NUM_TRACKS, METADATA_TYPE_LONG);
         METADATA_KEYS_TYPE.put(METADATA_KEY_DISC_NUMBER, METADATA_TYPE_LONG);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ARTIST, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ARTIST, METADATA_TYPE_TEXT);
         METADATA_KEYS_TYPE.put(METADATA_KEY_ART, METADATA_TYPE_BITMAP);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_ART_URI, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ART_URI, METADATA_TYPE_URI);
         METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ART, METADATA_TYPE_BITMAP);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ART_URI, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ART_URI, METADATA_TYPE_URI);
         METADATA_KEYS_TYPE.put(METADATA_KEY_USER_RATING, METADATA_TYPE_RATING);
         METADATA_KEYS_TYPE.put(METADATA_KEY_RATING, METADATA_TYPE_RATING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_TITLE, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_SUBTITLE, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_DESCRIPTION, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_ICON, METADATA_TYPE_BITMAP);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_ICON_URI, METADATA_TYPE_URI);
     }
 
     private static final SparseArray<String> EDITOR_KEY_MAPPING;
@@ -207,6 +278,7 @@
     }
 
     private final Bundle mBundle;
+    private Description mDescription;
 
     private MediaMetadata(Bundle bundle) {
         mBundle = new Bundle(bundle);
@@ -232,10 +304,27 @@
      * associated with the key.
      *
      * @param key The key the value is stored under
+     * @return a CharSequence value, or null
+     */
+    public CharSequence getText(String key) {
+        return mBundle.getCharSequence(key);
+    }
+
+    /**
+     * Returns the text value associated with the given key as a String, or null
+     * if no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key. This is equivalent to
+     * calling {@link #getText getText().toString()} if the value is not null.
+     *
+     * @param key The key the value is stored under
      * @return a String value, or null
      */
     public String getString(String key) {
-        return mBundle.getString(key);
+        CharSequence text = getText(key);
+        if (text != null) {
+            return text.toString();
+        }
+        return null;
     }
 
     /**
@@ -250,8 +339,8 @@
     }
 
     /**
-     * Return a {@link Rating} for the given key or null if no rating exists for
-     * the given key.
+     * Returns a {@link Rating} for the given key or null if no rating exists
+     * for the given key.
      *
      * @param key The key the value is stored under
      * @return A {@link Rating} or null
@@ -268,8 +357,8 @@
     }
 
     /**
-     * Return a {@link Bitmap} for the given key or null if no bitmap exists for
-     * the given key.
+     * Returns a {@link Bitmap} for the given key or null if no bitmap exists
+     * for the given key.
      *
      * @param key The key the value is stored under
      * @return A {@link Bitmap} or null
@@ -296,7 +385,7 @@
     }
 
     /**
-     * Get the number of fields in this metadata.
+     * Returns the number of fields in this metadata.
      *
      * @return The number of fields in the metadata.
      */
@@ -314,6 +403,64 @@
     }
 
     /**
+     * Returns a simple description of this metadata for display purposes.
+     *
+     * @return A simple description of this metadata.
+     * @hide
+     */
+    public @NonNull Description getDescription() {
+        if (mDescription != null) {
+            return mDescription;
+        }
+
+        CharSequence[] text = new CharSequence[3];
+        Bitmap icon = null;
+        Uri iconUri = null;
+
+        // First handle the case where display data is set already
+        CharSequence displayText = getText(METADATA_KEY_DISPLAY_TITLE);
+        if (!TextUtils.isEmpty(displayText)) {
+            // If they have a display title use only display data, otherwise use
+            // our best bets
+            text[0] = displayText;
+            text[1] = getText(METADATA_KEY_DISPLAY_SUBTITLE);
+            text[2] = getText(METADATA_KEY_DISPLAY_DESCRIPTION);
+        } else {
+            // Use whatever fields we can
+            int textIndex = 0;
+            int keyIndex = 0;
+            while (textIndex < text.length && keyIndex < PREFERRED_DESCRIPTION_ORDER.length) {
+                CharSequence next = getText(PREFERRED_DESCRIPTION_ORDER[keyIndex++]);
+                if (!TextUtils.isEmpty(next)) {
+                    // Fill in the next empty bit of text
+                    text[textIndex++] = next;
+                }
+            }
+        }
+
+        // Get the best art bitmap we can find
+        for (int i = 0; i < PREFERRED_BITMAP_ORDER.length; i++) {
+            Bitmap next = getBitmap(PREFERRED_BITMAP_ORDER[i]);
+            if (next != null) {
+                icon = next;
+                break;
+            }
+        }
+
+        // Get the best Uri we can find
+        for (int i = 0; i < PREFERRED_URI_ORDER.length; i++) {
+            String next = getString(PREFERRED_URI_ORDER[i]);
+            if (!TextUtils.isEmpty(next)) {
+                iconUri = Uri.parse(next);
+                break;
+            }
+        }
+
+        mDescription = new Description(text[0], text[1], text[2], icon, iconUri);
+        return mDescription;
+    }
+
+    /**
      * Helper for getting the String key used by {@link MediaMetadata} from the
      * integer key that {@link MediaMetadataEditor} uses.
      *
@@ -365,6 +512,43 @@
         }
 
         /**
+         * Put a CharSequence value into the metadata. Custom keys may be used,
+         * but if the METADATA_KEYs defined in this class are used they may only
+         * be one of the following:
+         * <ul>
+         * <li>{@link #METADATA_KEY_TITLE}</li>
+         * <li>{@link #METADATA_KEY_ARTIST}</li>
+         * <li>{@link #METADATA_KEY_ALBUM}</li>
+         * <li>{@link #METADATA_KEY_AUTHOR}</li>
+         * <li>{@link #METADATA_KEY_WRITER}</li>
+         * <li>{@link #METADATA_KEY_COMPOSER}</li>
+         * <li>{@link #METADATA_KEY_DATE}</li>
+         * <li>{@link #METADATA_KEY_GENRE}</li>
+         * <li>{@link #METADATA_KEY_ALBUM_ARTIST}</li>
+         * <li>{@link #METADATA_KEY_ART_URI}</li>
+         * <li>{@link #METADATA_KEY_ALBUM_ART_URI}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_TITLE}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_SUBTITLE}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_DESCRIPTION}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_ICON_URI}</li>
+         * </ul>
+         *
+         * @param key The key for referencing this value
+         * @param value The CharSequence value to store
+         * @return The Builder to allow chaining
+         */
+        public Builder putText(String key, CharSequence value) {
+            if (METADATA_KEYS_TYPE.containsKey(key)) {
+                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_TEXT) {
+                    throw new IllegalArgumentException("The " + key
+                            + " key cannot be used to put a CharSequence");
+                }
+            }
+            mBundle.putCharSequence(key, value);
+            return this;
+        }
+
+        /**
          * Put a String value into the metadata. Custom keys may be used, but if
          * the METADATA_KEYs defined in this class are used they may only be one
          * of the following:
@@ -380,6 +564,10 @@
          * <li>{@link #METADATA_KEY_ALBUM_ARTIST}</li>
          * <li>{@link #METADATA_KEY_ART_URI}</li>
          * <li>{@link #METADATA_KEY_ALBUM_ART_URI}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_TITLE}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_SUBTITLE}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_DESCRIPTION}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_ICON_URI}</li>
          * </ul>
          *
          * @param key The key for referencing this value
@@ -388,12 +576,12 @@
          */
         public Builder putString(String key, String value) {
             if (METADATA_KEYS_TYPE.containsKey(key)) {
-                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_STRING) {
+                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_TEXT) {
                     throw new IllegalArgumentException("The " + key
                             + " key cannot be used to put a String");
                 }
             }
-            mBundle.putString(key, value);
+            mBundle.putCharSequence(key, value);
             return this;
         }
 
@@ -410,7 +598,7 @@
          * </ul>
          *
          * @param key The key for referencing this value
-         * @param value The String value to store
+         * @param value The long value to store
          * @return The Builder to allow chaining
          */
         public Builder putLong(String key, long value) {
@@ -434,7 +622,7 @@
          * </ul>
          *
          * @param key The key for referencing this value
-         * @param value The String value to store
+         * @param value The Rating value to store
          * @return The Builder to allow chaining
          */
         public Builder putRating(String key, Rating value) {
@@ -455,6 +643,7 @@
          * <ul>
          * <li>{@link #METADATA_KEY_ART}</li>
          * <li>{@link #METADATA_KEY_ALBUM_ART}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_ICON}</li>
          * </ul>
          *
          * @param key The key for referencing this value
@@ -482,4 +671,46 @@
         }
     }
 
+    /**
+     * A simple form of the metadata that can be used for display.
+     *
+     * @hide
+     */
+    public final class Description {
+        /**
+         * A primary title suitable for display or null.
+         */
+        public final CharSequence title;
+        /**
+         * A subtitle suitable for display or null.
+         */
+        public final CharSequence subtitle;
+        /**
+         * A description suitable for display or null.
+         */
+        public final CharSequence description;
+        /**
+         * A bitmap icon suitable for display or null.
+         */
+        public final Bitmap icon;
+        /**
+         * A Uri for an icon suitable for display or null.
+         */
+        public final Uri iconUri;
+
+        private Description(CharSequence title, CharSequence subtitle, CharSequence description,
+                Bitmap icon, Uri iconUri) {
+            this.title = title;
+            this.subtitle = subtitle;
+            this.description = description;
+            this.icon = icon;
+            this.iconUri = iconUri;
+        }
+
+        @Override
+        public String toString() {
+            return title + ", " + subtitle + ", " + description;
+        }
+    }
+
 }
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
index db6315a..96c66c5 100644
--- a/media/java/android/media/RemoteControlClient.java
+++ b/media/java/android/media/RemoteControlClient.java
@@ -473,7 +473,7 @@
                 String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key);
                 // But just in case, don't add things we don't understand
                 if (metadataKey != null) {
-                    mMetadataBuilder.putString(metadataKey, value);
+                    mMetadataBuilder.putText(metadataKey, value);
                 }
             }
 
diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java
index 858383e..1c6d81f 100644
--- a/media/java/android/media/browse/MediaBrowser.java
+++ b/media/java/android/media/browse/MediaBrowser.java
@@ -225,6 +225,17 @@
     }
 
     /**
+     * Gets the service component that the media browser is connected to.
+     */
+    public @NonNull ComponentName getServiceComponent() {
+        if (!isConnected()) {
+            throw new IllegalStateException("getServiceComponent() called while not connected" +
+                    " (state=" + mState + ")");
+        }
+        return mServiceComponent;
+    }
+
+    /**
      * Gets the root Uri.
      * <p>
      * Note that the root uri may become invalid or change when when the
@@ -234,7 +245,7 @@
      * @throws IllegalStateException if not connected.
      */
     public @NonNull Uri getRoot() {
-        if (mState != CONNECT_STATE_CONNECTED) {
+        if (!isConnected()) {
             throw new IllegalStateException("getSessionToken() called while not connected (state="
                     + getStateLabel(mState) + ")");
         }
@@ -247,7 +258,7 @@
      * @throws IllegalStateException if not connected.
      */
     public @Nullable Bundle getExtras() {
-        if (mState != CONNECT_STATE_CONNECTED) {
+        if (!isConnected()) {
             throw new IllegalStateException("getExtras() called while not connected (state="
                     + getStateLabel(mState) + ")");
         }
@@ -266,7 +277,7 @@
      * @throws IllegalStateException if not connected.
      */
      public @NonNull MediaSession.Token getSessionToken() {
-        if (mState != CONNECT_STATE_CONNECTED) {
+        if (!isConnected()) {
             throw new IllegalStateException("getSessionToken() called while not connected (state="
                     + mState + ")");
         }
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 382579c..e3c198e 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -196,6 +196,30 @@
     }
 
     /**
+     * Get the queue title for this session.
+     */
+    public @Nullable CharSequence getQueueTitle() {
+        try {
+            return mSessionBinder.getQueueTitle();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getQueueTitle", e);
+        }
+        return null;
+    }
+
+    /**
+     * Get the extras for this session.
+     */
+    public @Nullable Bundle getExtras() {
+        try {
+            return mSessionBinder.getExtras();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getExtras", e);
+        }
+        return null;
+    }
+
+    /**
      * Get the rating type supported by the session. One of:
      * <ul>
      * <li>{@link Rating#RATING_NONE}</li>
diff --git a/media/java/android/media/tv/ITvInputClient.aidl b/media/java/android/media/tv/ITvInputClient.aidl
index 2c39afa..7a023d6 100644
--- a/media/java/android/media/tv/ITvInputClient.aidl
+++ b/media/java/android/media/tv/ITvInputClient.aidl
@@ -33,10 +33,11 @@
     void onSessionReleased(int seq);
     void onSessionEvent(in String name, in Bundle args, int seq);
     void onChannelRetuned(in Uri channelUri, int seq);
-    void onTrackInfoChanged(in List<TvTrackInfo> tracks, int seq);
-    void onTrackSelectionChanged(in List<TvTrackInfo> selectedTracks, int seq);
+    void onTracksChanged(in List<TvTrackInfo> tracks, int seq);
+    void onTrackSelected(int type, in String trackId, int seq);
     void onVideoAvailable(int seq);
     void onVideoUnavailable(int reason, int seq);
     void onContentAllowed(int seq);
     void onContentBlocked(in String rating, int seq);
+    void onLayoutSurface(int left, int top, int right, int bottom, int seq);
 }
diff --git a/media/java/android/media/tv/ITvInputHardware.aidl b/media/java/android/media/tv/ITvInputHardware.aidl
index f35e8f3..96223ba 100644
--- a/media/java/android/media/tv/ITvInputHardware.aidl
+++ b/media/java/android/media/tv/ITvInputHardware.aidl
@@ -33,14 +33,32 @@
      * trigger CEC commands for adjusting active HDMI source. Returns true on success.
      */
     boolean setSurface(in Surface surface, in TvStreamConfig config);
+
     /**
-     * Set volume for this stream via AudioGain. (TBD)
+     * Set volume for this stream via AudioGain.
      */
-    void setVolume(float volume);
+    void setStreamVolume(float volume);
 
     /**
      * Dispatch key event to HDMI service. The events would be automatically converted to
      * HDMI CEC commands. If the hardware is not representing an HDMI port, this method will fail.
      */
     boolean dispatchKeyEventToHdmi(in KeyEvent event);
+
+    /**
+     * Override default audio sink from audio policy. When override is on, it is
+     * TvInputService's responsibility to adjust to audio configuration change
+     * (for example, when the audio sink becomes unavailable or more desirable
+     * audio sink is detected).
+     *
+     * @param audioType one of AudioManager.DEVICE_* values. When it's * DEVICE_NONE, override
+     *        becomes off.
+     * @param audioAddress audio address of the overriding device.
+     * @param samplingRate desired sampling rate. Use default when it's 0.
+     * @param channelMask desired channel mask. Use default when it's
+     *        AudioFormat.CHANNEL_OUT_DEFAULT.
+     * @param format desired format. Use default when it's AudioFormat.ENCODING_DEFAULT.
+     */
+    void overrideAudioSink(int audioType, String audioAddress, int samplingRate, int channelMask,
+            int format);
 }
diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl
index a2b7d6b..20b8e7c 100644
--- a/media/java/android/media/tv/ITvInputManager.aidl
+++ b/media/java/android/media/tv/ITvInputManager.aidl
@@ -60,8 +60,7 @@
     void setVolume(in IBinder sessionToken, float volume, int userId);
     void tune(in IBinder sessionToken, in Uri channelUri, in Bundle params, int userId);
     void setCaptionEnabled(in IBinder sessionToken, boolean enabled, int userId);
-    void selectTrack(in IBinder sessionToken, in TvTrackInfo track, int userId);
-    void unselectTrack(in IBinder sessionToken, in TvTrackInfo track, int userId);
+    void selectTrack(in IBinder sessionToken, int type, in String trackId, int userId);
 
     void sendAppPrivateCommand(in IBinder sessionToken, in String action, in Bundle data,
             int userId);
@@ -83,4 +82,5 @@
     List<TvStreamConfig> getAvailableTvStreamConfigList(in String inputId, int userId);
     boolean captureFrame(in String inputId, in Surface surface, in TvStreamConfig config,
             int userId);
+    boolean isSingleSessionActive(int userId);
 }
diff --git a/media/java/android/media/tv/ITvInputService.aidl b/media/java/android/media/tv/ITvInputService.aidl
index 651669b..c98a48d 100644
--- a/media/java/android/media/tv/ITvInputService.aidl
+++ b/media/java/android/media/tv/ITvInputService.aidl
@@ -16,7 +16,7 @@
 
 package android.media.tv;
 
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.media.tv.ITvInputServiceCallback;
 import android.media.tv.ITvInputSessionCallback;
 import android.media.tv.TvInputHardwareInfo;
@@ -35,6 +35,6 @@
     // For hardware TvInputService
     void notifyHardwareAdded(in TvInputHardwareInfo hardwareInfo);
     void notifyHardwareRemoved(in TvInputHardwareInfo hardwareInfo);
-    void notifyHdmiCecDeviceAdded(in HdmiCecDeviceInfo cecDeviceInfo);
-    void notifyHdmiCecDeviceRemoved(in HdmiCecDeviceInfo cecDeviceInfo);
+    void notifyHdmiCecDeviceAdded(in HdmiDeviceInfo deviceInfo);
+    void notifyHdmiCecDeviceRemoved(in HdmiDeviceInfo deviceInfo);
 }
diff --git a/media/java/android/media/tv/ITvInputServiceCallback.aidl b/media/java/android/media/tv/ITvInputServiceCallback.aidl
index 26a0d20..df648e7 100644
--- a/media/java/android/media/tv/ITvInputServiceCallback.aidl
+++ b/media/java/android/media/tv/ITvInputServiceCallback.aidl
@@ -27,5 +27,4 @@
     void addHardwareTvInput(in int deviceID, in TvInputInfo inputInfo);
     void addHdmiCecTvInput(in int logicalAddress, in TvInputInfo inputInfo);
     void removeTvInput(in String inputId);
-    void setWrappedInputId(in String inputId, in String wrappedInputId);
 }
diff --git a/media/java/android/media/tv/ITvInputSession.aidl b/media/java/android/media/tv/ITvInputSession.aidl
index 9a0be25..99fb911 100644
--- a/media/java/android/media/tv/ITvInputSession.aidl
+++ b/media/java/android/media/tv/ITvInputSession.aidl
@@ -37,8 +37,7 @@
     void setVolume(float volume);
     void tune(in Uri channelUri, in Bundle params);
     void setCaptionEnabled(boolean enabled);
-    void selectTrack(in TvTrackInfo track);
-    void unselectTrack(in TvTrackInfo track);
+    void selectTrack(int type, in String trackId);
 
     void appPrivateCommand(in String action, in Bundle data);
 
diff --git a/media/java/android/media/tv/ITvInputSessionCallback.aidl b/media/java/android/media/tv/ITvInputSessionCallback.aidl
index 3773987..063d10d 100644
--- a/media/java/android/media/tv/ITvInputSessionCallback.aidl
+++ b/media/java/android/media/tv/ITvInputSessionCallback.aidl
@@ -27,13 +27,14 @@
  * @hide
  */
 oneway interface ITvInputSessionCallback {
-    void onSessionCreated(ITvInputSession session);
+    void onSessionCreated(ITvInputSession session, in IBinder hardwareSessionToken);
     void onSessionEvent(in String name, in Bundle args);
     void onChannelRetuned(in Uri channelUri);
-    void onTrackInfoChanged(in List<TvTrackInfo> tracks);
-    void onTrackSelectionChanged(in List<TvTrackInfo> selectedTracks);
+    void onTracksChanged(in List<TvTrackInfo> tracks);
+    void onTrackSelected(int type, in String trackId);
     void onVideoAvailable();
     void onVideoUnavailable(int reason);
     void onContentAllowed();
     void onContentBlocked(in String rating);
+    void onLayoutSurface(int left, int top, int right, int bottom);
 }
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index a809da9..5022cc1 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -49,12 +49,11 @@
     private static final int DO_TUNE = 6;
     private static final int DO_SET_CAPTION_ENABLED = 7;
     private static final int DO_SELECT_TRACK = 8;
-    private static final int DO_UNSELECT_TRACK = 9;
-    private static final int DO_APP_PRIVATE_COMMAND = 10;
-    private static final int DO_CREATE_OVERLAY_VIEW = 11;
-    private static final int DO_RELAYOUT_OVERLAY_VIEW = 12;
-    private static final int DO_REMOVE_OVERLAY_VIEW = 13;
-    private static final int DO_REQUEST_UNBLOCK_CONTENT = 14;
+    private static final int DO_APP_PRIVATE_COMMAND = 9;
+    private static final int DO_CREATE_OVERLAY_VIEW = 10;
+    private static final int DO_RELAYOUT_OVERLAY_VIEW = 11;
+    private static final int DO_REMOVE_OVERLAY_VIEW = 12;
+    private static final int DO_REQUEST_UNBLOCK_CONTENT = 13;
 
     private final HandlerCaller mCaller;
 
@@ -121,11 +120,9 @@
                 return;
             }
             case DO_SELECT_TRACK: {
-                mTvInputSessionImpl.selectTrack((TvTrackInfo) msg.obj);
-                return;
-            }
-            case DO_UNSELECT_TRACK: {
-                mTvInputSessionImpl.unselectTrack((TvTrackInfo) msg.obj);
+                SomeArgs args = (SomeArgs) msg.obj;
+                mTvInputSessionImpl.selectTrack((Integer) args.arg1, (String) args.arg2);
+                args.recycle();
                 return;
             }
             case DO_APP_PRIVATE_COMMAND: {
@@ -196,13 +193,8 @@
     }
 
     @Override
-    public void selectTrack(TvTrackInfo track) {
-        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SELECT_TRACK, track));
-    }
-
-    @Override
-    public void unselectTrack(TvTrackInfo track) {
-        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_UNSELECT_TRACK, track));
+    public void selectTrack(int type, String trackId) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_SELECT_TRACK, type, trackId));
     }
 
     @Override
diff --git a/media/java/android/media/tv/TvContentRating.java b/media/java/android/media/tv/TvContentRating.java
index 1ace775..2e4d031 100644
--- a/media/java/android/media/tv/TvContentRating.java
+++ b/media/java/android/media/tv/TvContentRating.java
@@ -88,14 +88,190 @@
  *         <td>String value</td>
  *         <td>Comments</td>
  *     </tr>
+ *     <!--tr>
+ *         <td>AM_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>AR_TV</td>
+ *         <td></td>
+ *     </tr-->
  *     <tr>
- *         <td>US_TVPG</td>
- *         <td>The TV Parental Guidelines for US TV content ratings</td>
+ *         <td>AU_TV</td>
+ *         <td>Australian TV Classification</td>
  *     </tr>
+ *     <!--tr>
+ *         <td>BG_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>BR_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>CA_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>CH_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>CL_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>CO_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <tr>
+ *         <td>DE_TV</td>
+ *         <td>The Germany television rating system</td>
+ *     </tr>
+ *     <!--tr>
+ *         <td>DK_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <tr>
+ *         <td>ES_TV</td>
+ *         <td>The Spanish rating system for television programs</td>
+ *     </tr>
+ *     <!--tr>
+ *         <td>FI_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <tr>
+ *         <td>FR_TV</td>
+ *         <td>The content rating system in French</td>
+ *     </tr>
+ *     <!--tr>
+ *         <td>GR_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>HK_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>HU_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>ID_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>IE_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>IL_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>IN_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>IS_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>IT_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>KH_TV</td>
+ *         <td></td>
+ *     </tr-->
  *     <tr>
  *         <td>KR_TV</td>
  *         <td>The South Korean television rating system</td>
  *     </tr>
+ *     <!--tr>
+ *         <td>MV_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>MX_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>MY_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <tr>
+ *         <td>NL_TV</td>
+ *         <td>The television rating system in the Netherlands</td>
+ *     </tr>
+ *     <!--tr>
+ *         <td>NZ_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>PE_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>PH_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>PL_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>PT_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>RO_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>RU_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>RS_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>SG_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>SI_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>TH_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>TR_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>TW_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>UA_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <tr>
+ *         <td>US_TVPG</td>
+ *         <td>The TV Parental Guidelines for US TV content ratings</td>
+ *     </tr>
+ *     <!--tr>
+ *         <td>VE_TV</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>ZA_TV</td>
+ *         <td></td>
+ *     </tr-->
  * </table>
  *
  * <u>System defined string for {@code rating}</u>
@@ -104,16 +280,435 @@
  *         <td>String value</td>
  *         <td>Comments</td>
  *     </tr>
+ *     <!--tr>
+ *         <td>AM_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>AR_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <tr>
+ *         <td>AU_TV_CTC</td>
+ *         <td>A rating string for {@code AU_TV}. The content has been assessed and approved for
+ *         advertising unclassified films. Any advertising of unclassified films must display the
+ *         CTC message.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>AU_TV_G</td>
+ *         <td>A rating string for {@code AU_TV}. The content is very mild in impact. The G
+ *         classification is suitable for everyone. G products may contain classifiable elements
+ *         such as language and themes that are very mild in impact. However, some G-classified
+ *         films may contain content that is not of interest to children.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>AU_TV_PG</td>
+ *         <td>A rating string for {@code AU_TV}. The content is mild in impact. The impact of PG
+ *         (Parental Guidance) classified films should be no higher than mild, but they may contain
+ *         content that children find confusing or upsetting and may require the guidance or parents
+ *         and guardians. They may, for example, contain classifiable elements such as language and
+ *         themes that are mild in impact. It is not recommended for viewing or playing by persons
+ *         under 15 without guidance from parents or guardians.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>AU_TV_M</td>
+ *         <td>A rating string for {@code AU_TV}. The content is moderate in impact. Films
+ *         classified M (Mature) contain content of a moderate impact and are recommended for
+ *         teenagers aged 15 years and over. Children under 15 may legally access this material
+ *         because it is an advisory category. However, M classified films may include classifiable
+ *         elements such as violence and nudity of moderate impact that are not recommended for
+ *         children under 15 years. Parents and guardians may need to find out more about the film’s
+ *         specific content, before deciding whether the material is suitable for their child.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>AU_TV_MA16</td>
+ *         <td>A rating string for {@code AU_TV}. The content is strong in impact. MA 15+ classified
+ *         material contains strong content and is legally restricted to persons 15 years and over.
+ *         It may contain classifiable elements such as sex scenes and drug use that are strong in
+ *         impact. A person may be asked to show proof of their age before hiring or purchasing an
+ *         MA 15+ film. Cinema staff may also request that the person show proof of their age before
+ *         allowing them to watch an MA 15+ film. Children under the age of 15 may not legally
+ *         watch, buy or hire MA 15+ classified material unless they are in the company of a parent
+ *         or adult guardian. Children under 15 who go to the cinema to see an MA 15+ film must be
+ *         accompanied by a parent or adult guardian for the duration of the film. The parent or
+ *         adult guardian must also purchase the movie ticket for the child. The guardian must be
+ *         an adult exercising parental control over the person under 15 years of age. The guardian
+ *         needs to be 18 years or older.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>AU_TV_R18</td>
+ *         <td>A rating string for {@code AU_TV}. The content is high in impact. R 18+ classified
+ *         material is restricted to adults. Such material may contain classifiable elements such as
+ *         sex scenes and drug use that are high in impact. Some material classified R18+ may be
+ *         offensive to sections of the adult community. A person may be asked for proof of their
+ *         age before purchasing, hiring or viewing R18+ films at a retail store or cinema.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>AU_TV_X18</td>
+ *         <td>A rating string for {@code AU_TV}. X 18+ films are restricted to adults. This
+ *         classification is a special and legally restricted category which contains only sexually
+ *         explicit content. That is, material which shows actual sexual intercourse and other
+ *         sexual activity between consenting adults. X18+ films are only available for sale or hire
+ *         in the ACT and the NT.</td>
+ *     </tr>
+ *     <!--tr>
+ *         <td>BG_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <tr>
+ *         <td>BR_TV_L</td>
+ *         <td>A rating string for {@code BR_TV}. This classification applies to works which contain
+ *         predominantly positive contents and which do not bring unsuitable elements subject to
+ *         ratings to ages higher than 10, such as the ones listed below:
+ *         <dl>
+ *         <dd><b>Violence</b>: Fantasy violence; display of arms with no violence; deaths with no
+ *         violence; bones and skeletons with no violence.</dd>
+ *         <dd><b>Sex and Nudity</b>: Non-erotic nudity.</dd>
+ *         <dd><b>Drugs</b>: Moderate or insinuated use of legal drugs.</dd>
+ *         </dl>
+ *         </td>
+ *     </tr>
+ *     <tr>
+ *         <td>BR_TV_10</td>
+ *         <td>A rating string for {@code BR_TV}. Not recommended for ages under 10. The following
+ *         contents are accepted for this age range:
+ *         <dl>
+ *         <dd><b>Violence</b>: Display of arms with violence; fear/tension; distress; bones and
+ *         skeletons with signs of violent acts; criminal acts without violence; derogatory
+ *         language.</dd>
+ *         <dd><b>Sex and Nudity</b>: Educational contents about sex.</dd>
+ *         <dd><b>Drugs</b>: Oral description of the use of legal drugs; discussion on the issue
+ *         "drug trafficking"; medicinal use of illegal drugs.</dd>
+ *         </dl>
+ *         </td>
+ *     </tr>
+ *     <tr>
+ *         <td>BR_TV_12</td>
+ *         <td>A rating string for {@code BR_TV}. Not recommended for ages under 12. The following
+ *         contents are accepted for this age range:
+ *         <dl>
+ *         <dd><b>Violence</b>: Violent act; body injury; description of violence; presence of
+ *         blood; victim's grief; natural or accidental death with violence; violent act against
+ *         animals; exposure to danger; showing people in embarrassing or degrading situations;
+ *         verbal aggression; obscenity; bullying; corpses; sexual harassment; overvaluation of the
+ *         physical beauty; overvaluation of consumption.</dd>
+ *         <dd><b>Sex and Nudity</b>: Veiled nudity; sexual innuendo; sexual fondling; masturbation;
+ *         foul language; sex content language; sex simulation; sexual appeal.</dd>
+ *         <dd><b>Drugs</b>: Use of legal drugs; inducing the use of legal drugs; irregular use of
+ *         medication; mention to illegal drugs.</dd>
+ *         </dl>
+ *         </td>
+ *     </tr>
+ *     <tr>
+ *         <td>BR_TV_14</td>
+ *         <td>A rating string for {@code BR_TV}. Not recommended for ages under 14. The following
+ *         contents are accepted for this age range:
+ *         <dl>
+ *         <dd><b>Violence</b>: Intentional death; stigma/prejudice.</dd>
+ *         <dd><b>Sex and Nudity</b>: Nudity; erotization; vulgarity; sexual intercourse;
+ *         prostitution.</dd>
+ *         <dd><b>Drugs</b>: Insinuation of the use of illegal drugs; verbal descriptions of the use
+ *         or trafficking of illegal drugs; discussion on the "decriminalization of illegal drugs".</dd>
+ *         </dl>
+ *         </td>
+ *     </tr>
+ *     <tr>
+ *         <td>BR_TV_16</td>
+ *         <td>A rating string for {@code BR_TV}. Not recommended for ages under 16. The following
+ *         contents are accepted for this age range:
+ *         <dl>
+ *         <dd><b>Violence</b>: Rape; sexual exploitation; sexual coercion; torture; mutilation;
+ *         suicide; gratuitous violence/banalization of violence; abortion, death penalty,
+ *         euthanasia.</dd>
+ *         <dd><b>Sex and Nudity</b>: Intense sexual intercourse.</dd>
+ *         <dd><b>Drugs</b>: Production or trafficking of any illegal drug; use of illegal drugs;
+ *         inducing the use of illegal drugs.</dd>
+ *         </dl>
+ *         </td>
+ *     </tr>
+ *     <tr>
+ *         <td>BR_TV_18</td>
+ *         <td>A rating string for {@code BR_TV}. Not recommended for ages under 18. The following
+ *         contents are accepted for this age range:
+ *         <dl>
+ *         <dd><b>Violence</b>:  Violence of high impact; exaltation, glamorization and/or
+ *         incitement to violence; cruelty; hate crimes; pedophilia.</dd>
+ *         <dd><b>Sex and Nudity</b>: Explicit sex; complex/strong impact sexual intercourses
+ *         (incest, group sex, violent fetish and pornography overall).</dd>
+ *         <dd><b>Drugs</b>:  Inciting the use of illegal drugs.</dd>
+ *         </dl>
+ *         </td>
+ *     </tr>
+ *     <!--tr>
+ *         <td>CA_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>CH_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>CL_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>CO_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <tr>
+ *         <td>DE_TV_ALL</td>
+ *         <td>Without restriction. There are time schedules and certain age groups which have to be
+ *         considered. {@code DE_TV_ALL} is scheduled in daytime (6:00AM – 8:00PM). However, cinema
+ *         films classified with "12" may be shown during the daytime, if they are not considered
+ *         harmful to younger children.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DE_TV_12</td>
+ *         <td>Suitable for 12 years and above. There are time schedules and certain age groups
+ *         which have to be considered. {@code DE_TV_12} is scheduled in primetime (from 8:00PM
+ *         – 10.00 p.m.).</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DE_TV_16</td>
+ *         <td>Suitable for 16 years and above. There are time schedules and certain age groups
+ *         which have to be considered. {@code DE_TV_16} is scheduled in late evening (from 10:00PM
+ *         - 11:00PM). </td>
+ *     </tr>
+ *     <tr>
+ *         <td>DE_TV_18</td>
+ *         <td>Suitable for 18 years and above. There are time schedules and certain age groups
+ *         which have to be considered. {@code DE_TV_18} is scheduled in late night (from 11:00PM
+ *         - 6:00AM). </td>
+ *     </tr>
+ *     <!--tr>
+ *         <td>DK_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <tr>
+ *         <td>ES_TV_ALL</td>
+ *         <td>A rating string for {@code ES_TV}. This rating is for programs for all ages.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_TV_I</td>
+ *         <td>A rating string for {@code ES_TV}. This rating is for the recommended programs
+ *         especially for children.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_TV_7</td>
+ *         <td>A rating string for {@code ES_TV}. This rating is for programs not recommended for
+ *         children under 7.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_TV_13</td>
+ *         <td>A rating string for {@code ES_TV}. This rating is for programs not recommended for
+ *         children under 13.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_TV_18</td>
+ *         <td>A rating string for {@code ES_TV}. This rating is for programs not recommended for
+ *         children under 18.</td>
+ *     </tr>
+ *     <!--tr>
+ *         <td>FI_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <tr>
+ *         <td>FR_TV_ALL</td>
+ *         <td>A rating string for {@code FR_TV}. According to CSA in France, if no rating appears,
+ *         the program is most likely appropriate for all ages. In Android TV, however,
+ *         {@code RATING_FR_ALL} is used for handling that case.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_TV_10</td>
+ *         <td>A rating string for {@code FR_TV}. This rating is for programs that are not
+ *         recommended for children under 10.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_TV_12</td>
+ *         <td>A rating string for {@code FR_TV}. This rating is for programs that are not
+ *         recommended for children under 12. Programs rated this are not allowed to air before
+ *         10:00 pm (Some channels and programs are subject to exception). </td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_TV_16</td>
+ *         <td>A rating string for {@code FR_TV}. This rating is for programs that are not
+ *         recommended for children under 16. Programs rated this are not allowed to air before
+ *         10:30 pm (Some channels and programs are subject to exception). </td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_TV_18</td>
+ *         <td>A rating string for {@code FR_TV}.  This rating is for programs that are not
+ *         recommended for persons under 18. Programs rated this are allowed between midnight and
+ *         5 am and only on some channels. The access to these programs is locked by a personal
+ *         password.</td>
+ *     </tr>
+ *     <!--tr>
+ *         <td>GR_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>HK_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>HU_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>ID_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>IE_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>IL_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>IN_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>IS_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>KH_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <tr>
+ *         <td>KR_TV_ALL</td>
+ *         <td>A rating string for {@code KR_TV}. This rating is for programs that are appropriate
+ *         for all ages. This program usually involves programs designed for children or families.
+ *         </td>
+ *     </tr>
+ *     <tr>
+ *         <td>KR_TV_7</td>
+ *         <td>A rating string for {@code KR_TV}. This rating is for programs that may contain
+ *         material inappropriate for children younger than 7, and parental guidance is required.
+ *         </td>
+ *     </tr>
+ *     <tr>
+ *         <td>KR_TV_12</td>
+ *         <td>A rating string for {@code KR_TV}. This rating is for programs that may contain
+ *         material inappropriate for children younger than 12, and parental guidance is required.
+ *         </td>
+ *     </tr>
+ *     <tr>
+ *         <td>KR_TV_15</td>
+ *         <td>A rating string for {@code KR_TV}. This rating is for programs that may contain
+ *         material inappropriate for children younger than 15, and parental guidance is required.
+ *     </tr>
+ *     <tr>
+ *         <td>KR_TV_19</td>
+ *         <td>A rating string for {@code KR_TV}. This rating is for programs designed for adults
+ *         only.</td>
+ *     </tr>
+ *     <!--tr>
+ *         <td>MV_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>MX_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>MY_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <tr>
+ *         <td>NL_TV_AL</td>
+ *         <td>A rating string for {@code NL_TV}. This rating is for programs that are appropriate
+ *         for all ages.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>NL_TV_6</td>
+ *         <td>A rating string for {@code NL_TV}. This rating is for programs that require parental
+ *         advisory for children under 6.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>NL_TV_9</td>
+ *         <td>A rating string for {@code NL_TV}. This rating is for programs that require parental
+ *         advisory for children under 9.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>NL_TV_12</td>
+ *         <td>A rating string for {@code NL_TV}. This rating is for programs that require parental
+ *         advisory for children under 12.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>NL_TV_16</td>
+ *         <td>A rating string for {@code NL_TV}. This rating is for programs that require parental
+ *         advisory for children under 16.</td>
+ *     </tr>
+ *     <!--tr>
+ *         <td>NZ_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>PE_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>PH_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>PL_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>PT_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>RO_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>RU_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>RS_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>SG_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>SI_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>TH_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>TR_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>TW_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>UA_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
  *     <tr>
  *         <td>US_TVPG_TV_Y</td>
- *         <td>A rating string for the US_TVPG domain. Programs rated this are designed to be
+ *         <td>A rating string for {@code US_TVPG}. Programs rated this are designed to be
  *         appropriate for all children. Whether animated or live-action, the themes and elements
  *         in this program are specifically designed for a very young audience, including children
  *         from ages 2-6. This program is not expected to frighten younger children.</td>
  *     </tr>
  *     <tr>
  *         <td>US_TVPG_TV_Y7</td>
- *         <td>A rating string for the US_TVPG domain. Programs rated this are designed for children
+ *         <td>A rating string for {@code US_TVPG}. Programs rated this are designed for children
  *         age 7 and above. It may be more appropriate for children who have acquired the
  *         developmental skills needed to distinguish between make-believe and reality. Themes and
  *         elements in this program may include mild fantasy violence or comedic violence, or may
@@ -124,7 +719,7 @@
  *     </tr>
  *     <tr>
  *         <td>US_TVPG_TV_G</td>
- *         <td>A rating string for the US_TVPG domain. Most parents would find this program suitable
+ *         <td>A rating string for {@code US_TVPG}. Most parents would find this program suitable
  *         for all ages. Although this rating does not signify a program designed specifically for
  *         children, most parents may let younger children watch this program unattended. It
  *         contains little or no violence, no strong language and little or no sexual dialogue or
@@ -132,69 +727,39 @@
  *     </tr>
  *     <tr>
  *         <td>US_TVPG_TV_PG</td>
- *         <td>A rating string for the US_TVPG domain. Programs rated this contain material that
+ *         <td>A rating string for {@code US_TVPG}. Programs rated this contain material that
  *         parents may find unsuitable for younger children. Many parents may want to watch it with
  *         their younger children. The theme itself may call for parental guidance and/or the
- *         program may contain one or more of the following: some suggestive dialogue (US_TVPG_D),
- *         infrequent coarse language (US_TVPG_L), some sexual situations (US_TVPG_S), or moderate
- *         violence (US_TVPG_V).</td>
+ *         program may contain one or more of the following: some suggestive dialogue (
+ *         {@code US_TVPG_D}), infrequent coarse language ({@code US_TVPG_L}), some sexual
+ *         situations ({@code US_TVPG_S}), or moderate violence ({@code US_TVPG_V}).</td>
  *     </tr>
  *     <tr>
  *         <td>US_TVPG_TV_14</td>
- *         <td>A rating string for the US_TVPG domain. Programs rated this contains some material
+ *         <td>A rating string for {@code US_TVPG}. Programs rated this contains some material
  *         that many parents would find unsuitable for children under 14 years of age. Parents are
  *         strongly urged to exercise greater care in monitoring this program and are cautioned
  *         against letting children under the age of 14 watch unattended. This program may contain
- *         one or more of the following: intensely suggestive dialogue (US_TVPG_D), strong coarse
- *         language (US_TVPG_L), intense sexual situations (US_TVPG_S), or intense violence
- *         (US_TVPG_V).</td>
+ *         one or more of the following: intensely suggestive dialogue ({@code US_TVPG_D}), strong
+ *         coarse language ({@code US_TVPG_L}), intense sexual situations ({@code US_TVPG_S}), or
+ *         intense violence ({@code US_TVPG_V}).</td>
  *     </tr>
  *     <tr>
  *         <td>US_TVPG_TV_MA</td>
- *         <td>A rating string for the US_TVPG domain. Programs rated TV-MA are specifically
+ *         <td>A rating string for {@code US_TVPG}. Programs rated TV-MA are specifically
  *         designed to be viewed by adults and therefore may be unsuitable for children under 17.
  *         This program may contain one or more of the following: crude indecent language
- *         (US_TVPG_L), explicit sexual activity (US_TVPG_S), or graphic violence (US_TVPG_V).</td>
+ *         ({@code US_TVPG_L}), explicit sexual activity ({@code US_TVPG_S}), or graphic violence
+ *         ({@code US_TVPG_V}).</td>
  *     </tr>
- *     <tr>
- *         <td>KR_TV_ALL</td>
- *         <td>A rating string for the KR_TV domain. This rating is for programs that are
- *         appropriate for all ages. This program usually involves programs designed for children or
- *         families. This rating does not have an icon.</td>
- *     </tr>
- *     <tr>
- *         <td>KR_TV_7</td>
- *         <td>A rating string for the KR_TV domain. This rating is for programs that may contain
- *         material inappropriate for children younger than 7, and parental discretion should be
- *         used. Some cartoon programs not deemed strictly as "educational", and films rated "G" or
- *         "PG" in North America may fall into the 7 category.</td>
- *     </tr>
- *     <tr>
- *         <td>KR_TV_12</td>
- *         <td>A rating string for the KR_TV domain. This rating is for programs that may deemed
- *         inappropriate for those younger than 12, and parental discretion should be used. Usually
- *         used for animations that have stronger themes or violence then those designed for
- *         children, or for reality shows that have mild violence, themes, or language.</td>
- *     </tr>
- *     <tr>
- *         <td>KR_TV_15</td>
- *         <td>A rating string for the KR_TV domain. This rating is for programs that contain
- *         material that may be inappropriate for children under 15, and that parental discretion
- *         should be used. Examples include most dramas, and talk shows on OTA (over-the-air) TV
- *         (KBS, MBC, SBS), and many American TV shows/dramas on Cable TV channels like OCN and
- *         OnStyle. The programs that have this rating may include moderate or strong adult themes,
- *         language, sexual inference, and violence. As with the TV-14 rating in North America, this
- *         rating is commonly applied to live events where the occurrence of inappropriate dialogue
- *         is unpredictable. Since 2007, this rating is the most used rating for TV.</td>
- *     </tr>
- *     <tr>
- *         <td>KR_TV_19</td>
- *         <td>A rating string for the KR_TV domain. This rating is for programs that are intended
- *         for adults only. 19-rated programs cannot air during the hours of 7:00AM to 9:00AM, and
- *         1:00PM to 10:00PM. Programs that receive this rating will almost certainly have adult
- *         themes, sexual situations, frequent use of strong language and disturbing scenes of
- *         violence.</td>
- *     </tr>
+ *     <!--tr>
+ *         <td>VE_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>ZA_TV_ALL</td>
+ *         <td></td>
+ *     </tr-->
  * </table>
  *
  * <u>System defined string for {@code subRating}</u>
@@ -203,6 +768,170 @@
  *         <td>String value</td>
  *         <td>Comments</td>
  *     </tr>
+ *     <!--tr>
+ *         <td>AM_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>AR_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>BG_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>CA_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>CH_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>CL_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>CO_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>DK_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>FI_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>GR_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>HK_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>HU_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>ID_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>IE_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>IL_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>IN_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>IS_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>KH_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>MV_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>MX_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>MY_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <tr>
+ *         <td>NL_TV_V</td>
+ *         <td>Violence</td>
+ *     </tr>
+ *     <tr>
+ *         <td>NL_TV_F</td>
+ *         <td>Fear</td>
+ *     </tr>
+ *     <tr>
+ *         <td>NL_TV_S</td>
+ *         <td>Sex</td>
+ *     </tr>
+ *     <tr>
+ *         <td>NL_TV_D</td>
+ *         <td>Discrimination</td>
+ *     </tr>
+ *     <tr>
+ *         <td>NL_TV_DA</td>
+ *         <td>Drugs- and alcoholabuse</td>
+ *     </tr>
+ *     <tr>
+ *         <td>NL_TV_L</td>
+ *         <td>Coarse Language</td>
+ *     </tr>
+ *     <!--tr>
+ *         <td>NZ_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>PE_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>PH_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>PL_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>PT_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>RO_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>RU_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>RS_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>SG_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>SI_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>TH_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>TR_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>TW_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>UA_TV_</td>
+ *         <td></td>
+ *     </tr-->
  *     <tr>
  *         <td>US_TVPG_D</td>
  *         <td>Suggestive dialogue (Not used with US_TVPG_TV_MA)</td>
@@ -223,6 +952,14 @@
  *         <td>US_TVPG_FV</td>
  *         <td>Fantasy violence (exclusive to US_TVPG_TV_Y7)</td>
  *     </tr>
+ *     <!--tr>
+ *         <td>VE_TV_</td>
+ *         <td></td>
+ *     </tr-->
+ *     <!--tr>
+ *         <td>ZA_TV_</td>
+ *         <td></td>
+ *     </tr-->
  * </table>
  */
 public final class TvContentRating {
@@ -237,7 +974,6 @@
     private static final String DELIMITER = "/";
 
     private final String mDomain;
-    private final String mCountryCode;
     private final String mRatingSystem;
     private final String mRating;
     private final String[] mSubRatings;
@@ -246,21 +982,20 @@
      * Creates a TvContentRating object.
      *
      * @param domain The domain name.
-     * @param countryCode The country code in ISO 3166-2 format or {@code null}.
      * @param ratingSystem The rating system id.
      * @param rating The content rating string.
      * @param subRatings The string array of sub-ratings.
      * @return A TvContentRating object, or null if creation failed.
      */
-    public static TvContentRating createRating(String domain, String countryCode,
-            String ratingSystem, String rating, String... subRatings) {
+    public static TvContentRating createRating(String domain, String ratingSystem,
+            String rating, String... subRatings) {
         if (TextUtils.isEmpty(domain)) {
             throw new IllegalArgumentException("domain cannot be empty");
         }
         if (TextUtils.isEmpty(rating)) {
             throw new IllegalArgumentException("rating cannot be empty");
         }
-        return new TvContentRating(domain, countryCode, ratingSystem, rating, subRatings);
+        return new TvContentRating(domain, ratingSystem, rating, subRatings);
     }
 
     /**
@@ -268,7 +1003,7 @@
      * {@link #flattenToString}.
      *
      * @param ratingString The String that was returned by flattenToString().
-     * @return a new TvContentRating containing the domain, countryCode, rating system, rating and
+     * @return a new TvContentRating containing the domain, rating system, rating and
      *         sub-ratings information was encoded in {@code ratingString}.
      * @see #flattenToString
      */
@@ -277,27 +1012,28 @@
             throw new IllegalArgumentException("ratingString cannot be empty");
         }
         String[] strs = ratingString.split(DELIMITER);
-        if (strs.length < 4) {
+        if (strs.length < 3) {
             throw new IllegalArgumentException("Invalid rating string: " + ratingString);
         }
-        if (strs.length > 4) {
-            String[] subRatings = new String[strs.length - 4];
-            System.arraycopy(strs, 4, subRatings, 0, subRatings.length);
-            return new TvContentRating(strs[0], strs[1], strs[2], strs[3], subRatings);
+        if (strs.length > 3) {
+            String[] subRatings = new String[strs.length - 3];
+            System.arraycopy(strs, 3, subRatings, 0, subRatings.length);
+            return new TvContentRating(strs[0], strs[1], strs[2], subRatings);
         }
-        return new TvContentRating(strs[0], strs[1], strs[2], strs[3], null);
+        return new TvContentRating(strs[0], strs[1], strs[2], null);
     }
 
     /**
      * Constructs a TvContentRating object from a given rating and sub-rating constants.
      *
-     * @param rating The rating constant defined in this class.
+     * @param domain The domain name.
+     * @param ratingSystem The rating system id.
+     * @param rating The content rating string.
      * @param subRatings The String array of sub-rating constants defined in this class.
      */
-    private TvContentRating(String domain, String countryCode,
-            String ratingSystem, String rating, String[] subRatings) {
+    private TvContentRating(
+            String domain, String ratingSystem, String rating, String[] subRatings) {
         mDomain = domain;
-        mCountryCode = countryCode;
         mRatingSystem = ratingSystem;
         mRating = rating;
         mSubRatings = subRatings;
@@ -311,13 +1047,6 @@
     }
 
     /**
-     * Returns the country code in ISO 3166-2 format or {@code null}.
-     */
-    public String getCountry() {
-        return mCountryCode;
-    }
-
-    /**
      * Returns the rating system id.
      */
     public String getRatingSystem() {
@@ -341,7 +1070,6 @@
         return Collections.unmodifiableList(Arrays.asList(mSubRatings));
     }
 
-
     /**
      * Returns a String that unambiguously describes both the rating and sub-rating information
      * contained in the TvContentRating. You can later recover the TvContentRating from this string
@@ -355,8 +1083,6 @@
         StringBuilder builder = new StringBuilder();
         builder.append(mDomain);
         builder.append(DELIMITER);
-        builder.append(mCountryCode);
-        builder.append(DELIMITER);
         builder.append(mRatingSystem);
         builder.append(DELIMITER);
         builder.append(mRating);
diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java
index bc0538c..8feb7e6 100644
--- a/media/java/android/media/tv/TvInputInfo.java
+++ b/media/java/android/media/tv/TvInputInfo.java
@@ -29,7 +29,7 @@
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.graphics.drawable.Drawable;
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -152,10 +152,10 @@
 
     /**
      * Create a new instance of the TvInputInfo class,
-     * instantiating it from the given Context, ResolveInfo, and HdmiCecDeviceInfo.
+     * instantiating it from the given Context, ResolveInfo, and HdmiDeviceInfo.
      *
      * @param service The ResolveInfo returned from the package manager about this TV input service.
-     * @param cecInfo The HdmiCecDeviceInfo for a HDMI CEC logical device.
+     * @param cecInfo The HdmiDeviceInfo for a HDMI CEC logical device.
      * @param parentId The ID of this TV input's parent input. {@code null} if none exists.
      * @param iconUri The {@link android.net.Uri} to load the icon image.
      *        {@see android.content.ContentResolver#openInputStream}. If it is null, the application
@@ -166,7 +166,7 @@
      */
     @SystemApi
     public static TvInputInfo createTvInputInfo(Context context, ResolveInfo service,
-            HdmiCecDeviceInfo cecInfo, String parentId, String label, Uri iconUri)
+            HdmiDeviceInfo cecInfo, String parentId, String label, Uri iconUri)
                     throws XmlPullParserException, IOException {
         boolean isConnectedToHdmiSwitch = (cecInfo.getPhysicalAddress() & 0x0FFF) != 0;
         return createTvInputInfo(context, service, generateInputIdForHdmiCec(
@@ -494,14 +494,14 @@
     }
 
     /**
-     * Used to generate an input id from a ComponentName and HdmiCecDeviceInfo.
+     * Used to generate an input id from a ComponentName and HdmiDeviceInfo.
      *
      * @param name the component name for generating an input id.
-     * @param cecInfo HdmiCecDeviceInfo describing this TV input.
+     * @param cecInfo HdmiDeviceInfo describing this TV input.
      * @return the generated input id for the given {@code name} and {@code cecInfo}.
      */
     private static final String generateInputIdForHdmiCec(
-            ComponentName name, HdmiCecDeviceInfo cecInfo) {
+            ComponentName name, HdmiDeviceInfo cecInfo) {
         // Example of the format : "/CEC%04X%02X"
         String format = String.format("%s%s%%0%sX%%0%sX", DELIMITER_INFO_IN_ID, PREFIX_CEC_DEVICE,
                 LENGTH_CEC_PHYSICAL_ADDRESS, LENGTH_CEC_LOGICAL_ADDRESS);
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 0334083..6e075b2 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -176,16 +176,20 @@
          * @param session A {@link TvInputManager.Session} associated with this callback.
          * @param tracks A list which includes track information.
          */
-        public void onTrackInfoChanged(Session session, List<TvTrackInfo> tracks) {
+        public void onTracksChanged(Session session, List<TvTrackInfo> tracks) {
         }
 
         /**
-         * This is called when there is a change on the selected tracks in this session.
+         * This is called when a track for a given type is selected.
          *
          * @param session A {@link TvInputManager.Session} associated with this callback
-         * @param selectedTracks A list of selected tracks.
+         * @param type The type of the selected track. The type can be
+         *            {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or
+         *            {@link TvTrackInfo#TYPE_SUBTITLE}.
+         * @param trackId The ID of the selected track. When {@code null} the currently selected
+         *            track for a given type should be unselected.
          */
-        public void onTrackSelectionChanged(Session session, List<TvTrackInfo> selectedTracks) {
+        public void onTrackSelected(Session session, int type, String trackId) {
         }
 
         /**
@@ -231,6 +235,21 @@
         }
 
         /**
+         * This is called when {@link TvInputService.Session#layoutSurface} is called to
+         * change the layout of surface.
+         *
+         * @param session A {@link TvInputManager.Session} associated with this callback
+         * @param l Left position.
+         * @param t Top position.
+         * @param r Right position.
+         * @param b Bottom position.
+         * @hide
+         */
+        @SystemApi
+        public void onLayoutSurface(Session session, int left, int top, int right, int bottom) {
+        }
+
+        /**
          * This is called when a custom event has been sent from this session.
          *
          * @param session A {@link TvInputManager.Session} associated with this callback
@@ -282,22 +301,44 @@
             });
         }
 
-        public void postTrackInfoChanged(final List<TvTrackInfo> tracks) {
+        public void postTracksChanged(final List<TvTrackInfo> tracks) {
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    mSession.mTracks = tracks;
-                    mSessionCallback.onTrackInfoChanged(mSession, tracks);
+                    mSession.mAudioTracks.clear();
+                    mSession.mVideoTracks.clear();
+                    mSession.mSubtitleTracks.clear();
+                    for (TvTrackInfo track : tracks) {
+                        if (track.getType() == TvTrackInfo.TYPE_AUDIO) {
+                            mSession.mAudioTracks.add(track);
+                        } else if (track.getType() == TvTrackInfo.TYPE_VIDEO) {
+                            mSession.mVideoTracks.add(track);
+                        } else if (track.getType() == TvTrackInfo.TYPE_SUBTITLE) {
+                            mSession.mSubtitleTracks.add(track);
+                        } else {
+                            // Silently ignore.
+                        }
+                    }
+                    mSessionCallback.onTracksChanged(mSession, tracks);
                 }
             });
         }
 
-        public void postTrackSelectionChanged(final List<TvTrackInfo> selectedTracks) {
+        public void postTrackSelected(final int type, final String trackId) {
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    mSession.mSelectedTracks = selectedTracks;
-                    mSessionCallback.onTrackSelectionChanged(mSession, selectedTracks);
+                    if (type == TvTrackInfo.TYPE_AUDIO) {
+                        mSession.mSelectedAudioTrackId = trackId;
+                    } else if (type == TvTrackInfo.TYPE_VIDEO) {
+                        mSession.mSelectedVideoTrackId = trackId;
+                    } else if (type == TvTrackInfo.TYPE_SUBTITLE) {
+                        mSession.mSelectedSubtitleTrackId = trackId;
+                    } else {
+                        // Silently ignore.
+                        return;
+                    }
+                    mSessionCallback.onTrackSelected(mSession, type, trackId);
                 }
             });
         }
@@ -338,6 +379,16 @@
             });
         }
 
+        public void postLayoutSurface(final int left, final int top, final int right,
+                final int bottom) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onLayoutSurface(mSession, left, top, right, bottom);
+                }
+            });
+        }
+
         public void postSessionEvent(final String eventType, final Bundle eventArgs) {
             mHandler.post(new Runnable() {
                 @Override
@@ -476,26 +527,26 @@
             }
 
             @Override
-            public void onTrackInfoChanged(List<TvTrackInfo> tracks, int seq) {
+            public void onTracksChanged(List<TvTrackInfo> tracks, int seq) {
                 synchronized (mSessionCallbackRecordMap) {
                     SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
                     if (record == null) {
                         Log.e(TAG, "Callback not found for seq " + seq);
                         return;
                     }
-                    record.postTrackInfoChanged(tracks);
+                    record.postTracksChanged(tracks);
                 }
             }
 
             @Override
-            public void onTrackSelectionChanged(List<TvTrackInfo> selectedTracks, int seq) {
+            public void onTrackSelected(int type, String trackId, int seq) {
                 synchronized (mSessionCallbackRecordMap) {
                     SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
                     if (record == null) {
                         Log.e(TAG, "Callback not found for seq " + seq);
                         return;
                     }
-                    record.postTrackSelectionChanged(selectedTracks);
+                    record.postTrackSelected(type, trackId);
                 }
             }
 
@@ -548,6 +599,18 @@
             }
 
             @Override
+            public void onLayoutSurface(int left, int top, int right, int bottom, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postLayoutSurface(left, top, right, bottom);
+                }
+            }
+
+            @Override
             public void onSessionEvent(String eventType, Bundle eventArgs, int seq) {
                 synchronized (mSessionCallbackRecordMap) {
                     SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
@@ -885,6 +948,20 @@
     }
 
     /**
+     * Returns true if there is only a single TV input session.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean isSingleSessionActive() {
+        try {
+            return mService.isSingleSessionActive(mUserId);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
      * The Session provides the per-session functionality of TV inputs.
      * @hide
      */
@@ -911,8 +988,12 @@
         private IBinder mToken;
         private TvInputEventSender mSender;
         private InputChannel mChannel;
-        private List<TvTrackInfo> mTracks;
-        private List<TvTrackInfo> mSelectedTracks;
+        private final List<TvTrackInfo> mAudioTracks = new ArrayList<TvTrackInfo>();
+        private final List<TvTrackInfo> mVideoTracks = new ArrayList<TvTrackInfo>();
+        private final List<TvTrackInfo> mSubtitleTracks = new ArrayList<TvTrackInfo>();
+        private String mSelectedAudioTrackId;
+        private String mSelectedVideoTrackId;
+        private String mSelectedSubtitleTrackId;
 
         private Session(IBinder token, InputChannel channel, ITvInputManager service, int userId,
                 int seq, SparseArray<SessionCallbackRecord> sessionCallbackRecordMap) {
@@ -942,7 +1023,7 @@
         }
 
         /**
-         * Set this as main session. See {@link TvView#setMainTvView} for about meaning of "main".
+         * Sets this as main session. See {@link TvView#setMainTvView} for about meaning of "main".
          * @hide
          */
         public void setMainSession() {
@@ -1045,7 +1126,12 @@
                 Log.w(TAG, "The session has been already released");
                 return;
             }
-            mTracks = null;
+            mAudioTracks.clear();
+            mVideoTracks.clear();
+            mSubtitleTracks.clear();
+            mSelectedAudioTrackId = null;
+            mSelectedVideoTrackId = null;
+            mSelectedSubtitleTrackId = null;
             try {
                 mService.tune(mToken, channelUri, params, mUserId);
             } catch (RemoteException e) {
@@ -1071,75 +1157,90 @@
         }
 
         /**
-         * Select a track.
+         * Selects a track.
          *
-         * @param track The track to be selected.
+         * @param type The type of the track to select. The type can be
+         *            {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or
+         *            {@link TvTrackInfo#TYPE_SUBTITLE}.
+         * @param trackId The ID of the track to select. When {@code null}, the currently selected
+         *            track of the given type will be unselected.
          * @see #getTracks()
          */
-        public void selectTrack(TvTrackInfo track) {
-            if (track == null) {
-                throw new IllegalArgumentException("track cannot be null");
+        public void selectTrack(int type, String trackId) {
+            if (type == TvTrackInfo.TYPE_AUDIO) {
+                if (trackId != null && !mAudioTracks.contains(trackId)) {
+                    Log.w(TAG, "Invalid audio trackId: " + trackId);
+                }
+            } else if (type == TvTrackInfo.TYPE_VIDEO) {
+                if (trackId != null && !mVideoTracks.contains(trackId)) {
+                    Log.w(TAG, "Invalid video trackId: " + trackId);
+                }
+            } else if (type == TvTrackInfo.TYPE_SUBTITLE) {
+                if (trackId != null && !mSubtitleTracks.contains(trackId)) {
+                    Log.w(TAG, "Invalid subtitle trackId: " + trackId);
+                }
+            } else {
+                throw new IllegalArgumentException("invalid type: " + type);
             }
             if (mToken == null) {
                 Log.w(TAG, "The session has been already released");
                 return;
             }
             try {
-                mService.selectTrack(mToken, track, mUserId);
+                mService.selectTrack(mToken, type, trackId, mUserId);
             } catch (RemoteException e) {
                 throw new RuntimeException(e);
             }
         }
 
         /**
-         * Unselect a track.
+         * Returns the list of tracks for a given type. Returns {@code null} if the information is
+         * not available.
          *
-         * @param track The track to be selected.
-         * @see #getTracks()
+         * @param type The type of the tracks. The type can be {@link TvTrackInfo#TYPE_AUDIO},
+         *            {@link TvTrackInfo#TYPE_VIDEO} or {@link TvTrackInfo#TYPE_SUBTITLE}.
+         * @return the list of tracks for the given type.
          */
-        public void unselectTrack(TvTrackInfo track) {
-            if (track == null) {
-                throw new IllegalArgumentException("track cannot be null");
+        public List<TvTrackInfo> getTracks(int type) {
+            if (type == TvTrackInfo.TYPE_AUDIO) {
+                if (mAudioTracks == null) {
+                    return null;
+                }
+                return mAudioTracks;
+            } else if (type == TvTrackInfo.TYPE_VIDEO) {
+                if (mVideoTracks == null) {
+                    return null;
+                }
+                return mVideoTracks;
+            } else if (type == TvTrackInfo.TYPE_SUBTITLE) {
+                if (mSubtitleTracks == null) {
+                    return null;
+                }
+                return mSubtitleTracks;
             }
-            if (mToken == null) {
-                Log.w(TAG, "The session has been already released");
-                return;
-            }
-            try {
-                mService.unselectTrack(mToken, track, mUserId);
-            } catch (RemoteException e) {
-                throw new RuntimeException(e);
-            }
+            throw new IllegalArgumentException("invalid type: " + type);
         }
 
         /**
-         * Returns a list which includes track information. May return {@code null} if the
-         * information is not available.
-         * @see #selectTrack(TvTrackInfo)
-         * @see #unselectTrack(TvTrackInfo)
+         * Returns the selected track for a given type. Returns {@code null} if the information is
+         * not available or any of the tracks for the given type is not selected.
+         *
+         * @return the ID of the selected track.
+         * @see #selectTrack
          */
-        public List<TvTrackInfo> getTracks() {
-            if (mTracks == null) {
-                return null;
+        public String getSelectedTrack(int type) {
+            if (type == TvTrackInfo.TYPE_AUDIO) {
+                return mSelectedAudioTrackId;
+            } else if (type == TvTrackInfo.TYPE_VIDEO) {
+                return mSelectedVideoTrackId;
+            } else if (type == TvTrackInfo.TYPE_SUBTITLE) {
+                return mSelectedSubtitleTrackId;
             }
-            return new ArrayList<TvTrackInfo>(mTracks);
+            throw new IllegalArgumentException("invalid type: " + type);
         }
 
         /**
-         * Returns a list of selected tracks May return {@code null} if the information is not
-         * available.
-         * @see #selectTrack(TvTrackInfo)
-         * @see #unselectTrack(TvTrackInfo)
-         */
-        public List<TvTrackInfo> getSelectedTracks() {
-            if (mSelectedTracks == null) {
-                return null;
-            }
-            return new ArrayList<TvTrackInfo>(mSelectedTracks);
-        }
-
-        /**
-         * Call {@link TvInputService.Session#appPrivateCommand(String, Bundle)
+         * Calls {@link TvInputService.Session#appPrivateCommand(String, Bundle)
          * TvInputService.Session.appPrivateCommand()} on the current TvView.
          *
          * @param action Name of the command to be performed. This <em>must</em> be a scoped name,
@@ -1404,6 +1505,10 @@
             mPendingEventPool.release(p);
         }
 
+        IBinder getToken() {
+            return mToken;
+        }
+
         private void releaseInternal() {
             mToken = null;
             synchronized (mHandler) {
diff --git a/media/java/android/media/tv/TvInputPassthroughWrapperService.java b/media/java/android/media/tv/TvInputPassthroughWrapperService.java
deleted file mode 100644
index 08c802f6..0000000
--- a/media/java/android/media/tv/TvInputPassthroughWrapperService.java
+++ /dev/null
@@ -1,259 +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.media.tv;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.os.Handler;
-import android.util.Log;
-import android.view.Surface;
-
-/**
- * TvInputPassthroughWrapperService represents a TV input which controls an external device
- * connected to a pass-through TV input (e.g. HDMI 1).
- * <p>
- * This service wraps around a pass-through TV input and delegates the {@link Surface} to the
- * connected TV input so that the application can show the pass-through TV input while
- * TvInputPassthroughWrapperService controls the underlying external device via a separate
- * connection. In the setup activity, the TV input should get the pass-through TV input ID, around
- * which this service will wrap. The service implementation should pass the ID via
- * {@link TvInputPassthroughWrapperService#getPassthroughInputId(String)}. In addition,
- * it needs to implement {@link TvInputPassthroughWrapperService#onCreatePassthroughWrapperSession}
- * to handle requests from the application.
- * </p>
- */
-public abstract class TvInputPassthroughWrapperService extends TvInputService {
-    private static final String TAG = "TvInputPassthroughWrapperService";
-    // STOPSHIP: Turn debugging off.
-    private static final boolean DEBUG = true;
-    private TvInputManager mTvInputManager;
-    private Handler mHandler;
-
-    @Override
-    public void onCreate() {
-        if (DEBUG) Log.d(TAG, "onCreate()");
-        super.onCreate();
-        mTvInputManager = (TvInputManager) getSystemService(Context.TV_INPUT_SERVICE);
-        mHandler = new Handler();
-    }
-
-    @Override
-    public final Session onCreateSession(String inputId) {
-        if (DEBUG) Log.d(TAG, "onCreateSession()");
-        // Checks the pass-through TV input is properly setup.
-        String passthroughInputId = getPassthroughInputId(inputId);
-        if (passthroughInputId == null) {
-            Log.w(TAG, "The passthrough TV input for input id(" + inputId + ") is not setup yet.");
-            return null;
-        }
-        // Checks if input id from the derived class is really pass-through type.
-        TvInputInfo info = mTvInputManager.getTvInputInfo(passthroughInputId);
-        if (info == null || !info.isPassthroughInputType()) {
-            Log.w(TAG, "Invalid TV input id from derived class: " + passthroughInputId);
-            return null;
-        }
-        // Creates a PassthroughWrapperSession.
-        PassthroughWrapperSession session = onCreatePassthroughWrapperSession();
-        if (session == null) {
-            return null;
-        }
-        // Connects to the pass-through input the external device is connected to.
-        if (!session.connect(passthroughInputId)) {
-            throw new IllegalStateException("WrapperSession cannot be reused.");
-        }
-        notifyWrappedInputId(inputId, passthroughInputId);
-        return session;
-    }
-
-    /**
-     * Returns an implementation of {@link PassthroughWrapperSession}.
-     * <p>
-     * May return {@code null} if {@link TvInputPassthroughWrapperService} fails to create a
-     * session.
-     * </p>
-     */
-    public abstract PassthroughWrapperSession onCreatePassthroughWrapperSession();
-
-    /**
-     * Returns the TV input id the external device is connected to.
-     * <p>
-     * {@link TvInputPassthroughWrapperService} is expected to identify the pass-though TV
-     * input the external device is connected to in the setup phase of this TV input.
-     * May return {@code null} if the pass-though TV input is not identified yet.
-     * </p>
-     * @param inputId The ID of the TV input which controls the external device.
-     */
-    public abstract String getPassthroughInputId(String inputId);
-
-    /**
-     * Base session class for derived classes to handle the request from the application. This
-     * creates additional session to the pass-through TV input internally and delegates the
-     * {@link Surface} given from the application.
-     */
-    public abstract class PassthroughWrapperSession extends Session {
-        private static final float VOLUME_ON = 1.0f;
-        private static final float VOLUME_OFF = 0f;
-        private TvInputManager.Session mSession;
-        private Surface mSurface;
-        private Float mVolume;
-        private boolean mReleased;
-        private int mSurfaceFormat;
-        private int mSurfaceWidth;
-        private int mSurfaceHeight;
-        private boolean mSurfaceChanged;
-        private boolean mConnectionRequested;
-
-        private final TvInputManager.SessionCallback mSessionCallback =
-                new TvInputManager.SessionCallback() {
-            @Override
-            public void onSessionCreated(TvInputManager.Session session) {
-                if (session == null) {
-                    Log.w(TAG, "Failed to create session.");
-                    onPassthroughSessionCreationFailed();
-                    return;
-                }
-                if (mReleased) {
-                    session.release();
-                    return;
-                }
-                if (mSurface != null) {
-                    session.setSurface(mSurface);
-                    mSurface = null;
-                }
-                if (mVolume != null) {
-                    session.setStreamVolume(mVolume);
-                    mVolume = null;
-                }
-                if (mSurfaceChanged) {
-                    session.dispatchSurfaceChanged(mSurfaceFormat, mSurfaceWidth, mSurfaceHeight);
-                    mSurfaceChanged = false;
-                }
-                mSession = session;
-            }
-
-            @Override
-            public void onSessionReleased(TvInputManager.Session session) {
-                mReleased = true;
-                mSession = null;
-                onPassthroughSessionReleased();
-            }
-
-            @Override
-            public void onVideoAvailable(TvInputManager.Session session) {
-                if (mSession == session) {
-                    onPassthroughVideoAvailable();
-                }
-            }
-
-            @Override
-            public void onVideoUnavailable(TvInputManager.Session session, int reason) {
-                if (mSession == session) {
-                    onPassthroughVideoUnavailable(reason);
-                }
-            }
-
-            @Override
-            public void onSessionEvent(TvInputManager.Session session, String eventType,
-                    Bundle eventArgs) {
-                if (mSession == session) {
-                    notifySessionEvent(eventType, eventArgs);
-                }
-            }
-        };
-
-        /**
-         * Called when failed to create a session for pass-through TV input.
-         */
-        public abstract void onPassthroughSessionCreationFailed();
-
-        /**
-         * Called when the pass-through TV input session is released. This typically happens when
-         * the process hosting the pass-through TV input has crashed or been killed.
-         */
-        public abstract void onPassthroughSessionReleased();
-
-        /**
-         * Called when the underlying pass-through TV input session calls
-         * {@link #notifyVideoAvailable()}.
-         */
-        public abstract void onPassthroughVideoAvailable();
-
-        /**
-         * Called when the underlying pass-through TV input session calls
-         * {@link #notifyVideoUnavailable(int)}.
-         *
-         * @param reason The reason why the pass-through TV input stopped the playback.
-         */
-        public abstract void onPassthroughVideoUnavailable(int reason);
-
-        @Override
-        public final boolean onSetSurface(Surface surface) {
-            if (DEBUG) Log.d(TAG, "onSetSurface(" + surface + ")");
-            if (mSession == null) {
-                mSurface = surface;
-            } else {
-                mSession.setSurface(surface);
-            }
-            return true;
-        }
-
-        private boolean connect(String inputId) {
-            if (mConnectionRequested) {
-                return false;
-            }
-            mTvInputManager.createSession(inputId, mSessionCallback, mHandler);
-            mConnectionRequested = true;
-            return true;
-        }
-
-        @Override
-        void release() {
-            super.release();
-            mReleased = true;
-            if (mSession != null) {
-                mSession.release();
-            }
-        }
-
-        @Override
-        void dispatchSurfaceChanged(int format, int width, int height) {
-            super.dispatchSurfaceChanged(format, width, height);
-            if (mSession == null) {
-                mSurfaceFormat = format;
-                mSurfaceWidth = width;
-                mSurfaceHeight = height;
-                mSurfaceChanged = true;
-            } else {
-                mSession.dispatchSurfaceChanged(format, width, height);
-            }
-        }
-
-        @Override
-        void setStreamVolume(float volume) {
-            super.setStreamVolume(volume);
-            // Here, we let the pass-through TV input know only whether volume is on or off and
-            // make the fine control done in the derived class to prevent that the volume is
-            // controlled in the both side.
-            float volumeForPassthriughInput = (volume > 0.0f) ? VOLUME_ON : VOLUME_OFF;
-            if (mSession == null) {
-                mVolume = Float.valueOf(volumeForPassthriughInput);
-            } else {
-                mSession.setStreamVolume(volumeForPassthriughInput);
-            }
-        }
-    }
-}
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 7ce278c..6a41c61 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -23,14 +23,16 @@
 import android.content.Intent;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.Gravity;
 import android.view.InputChannel;
@@ -40,6 +42,7 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.Surface;
+import android.view.SurfaceView;
 import android.view.View;
 import android.view.WindowManager;
 import android.view.accessibility.CaptioningManager;
@@ -47,7 +50,9 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.SomeArgs;
 
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 /**
  * The TvInputService class represents a TV input or source such as HDMI or built-in tuner which
@@ -83,7 +88,11 @@
      */
     public static final String SERVICE_META_DATA = "android.media.tv.input";
 
-    private final Handler mHandler = new ServiceHandler();
+    /**
+     * Handler instance to handle request from TV Input Manager Service. Should be run in the main
+     * looper to be synchronously run with {@code Session.mHandler}.
+     */
+    private Handler mServiceHandler = new ServiceHandler();
     private final RemoteCallbackList<ITvInputServiceCallback> mCallbacks =
             new RemoteCallbackList<ITvInputServiceCallback>();
 
@@ -117,30 +126,30 @@
                 args.arg1 = channel;
                 args.arg2 = cb;
                 args.arg3 = inputId;
-                mHandler.obtainMessage(ServiceHandler.DO_CREATE_SESSION, args).sendToTarget();
+                mServiceHandler.obtainMessage(ServiceHandler.DO_CREATE_SESSION, args).sendToTarget();
             }
 
             @Override
             public void notifyHardwareAdded(TvInputHardwareInfo hardwareInfo) {
-                mHandler.obtainMessage(ServiceHandler.DO_ADD_HARDWARE_TV_INPUT,
+                mServiceHandler.obtainMessage(ServiceHandler.DO_ADD_HARDWARE_TV_INPUT,
                         hardwareInfo).sendToTarget();
             }
 
             @Override
             public void notifyHardwareRemoved(TvInputHardwareInfo hardwareInfo) {
-                mHandler.obtainMessage(ServiceHandler.DO_REMOVE_HARDWARE_TV_INPUT,
+                mServiceHandler.obtainMessage(ServiceHandler.DO_REMOVE_HARDWARE_TV_INPUT,
                         hardwareInfo).sendToTarget();
             }
 
             @Override
-            public void notifyHdmiCecDeviceAdded(HdmiCecDeviceInfo cecDeviceInfo) {
-                mHandler.obtainMessage(ServiceHandler.DO_ADD_HDMI_CEC_TV_INPUT,
+            public void notifyHdmiCecDeviceAdded(HdmiDeviceInfo cecDeviceInfo) {
+                mServiceHandler.obtainMessage(ServiceHandler.DO_ADD_HDMI_CEC_TV_INPUT,
                         cecDeviceInfo).sendToTarget();
             }
 
             @Override
-            public void notifyHdmiCecDeviceRemoved(HdmiCecDeviceInfo cecDeviceInfo) {
-                mHandler.obtainMessage(ServiceHandler.DO_REMOVE_HDMI_CEC_TV_INPUT,
+            public void notifyHdmiCecDeviceRemoved(HdmiDeviceInfo cecDeviceInfo) {
+                mServiceHandler.obtainMessage(ServiceHandler.DO_REMOVE_HDMI_CEC_TV_INPUT,
                         cecDeviceInfo).sendToTarget();
             }
         };
@@ -159,6 +168,8 @@
      * Returns a concrete implementation of {@link Session}.
      * <p>
      * May return {@code null} if this TV input service fails to create a session for some reason.
+     * If TV input represents an external device connected to a hardware TV input,
+     * {@link HardwareSession} should be returned.
      * </p>
      * @param inputId The ID of the TV input associated with the session.
      */
@@ -195,11 +206,11 @@
      * {@code cecDeviceInfo}; otherwise, return {@code null}. Override to modify default behavior
      * of ignoring all HDMI CEC logical input device.
      *
-     * @param cecDeviceInfo {@link HdmiCecDeviceInfo} object just added.
+     * @param cecDeviceInfo {@link HdmiDeviceInfo} object just added.
      * @hide
      */
     @SystemApi
-    public TvInputInfo onHdmiCecDeviceAdded(HdmiCecDeviceInfo cecDeviceInfo) {
+    public TvInputInfo onHdmiCecDeviceAdded(HdmiDeviceInfo cecDeviceInfo) {
         return null;
     }
 
@@ -208,35 +219,21 @@
      * otherwise, return {@code null}. Override to modify default behavior of ignoring all HDMI CEC
      * logical input device.
      *
-     * @param cecDeviceInfo {@link HdmiCecDeviceInfo} object just removed.
+     * @param cecDeviceInfo {@link HdmiDeviceInfo} object just removed.
      * @hide
      */
     @SystemApi
-    public String onHdmiCecDeviceRemoved(HdmiCecDeviceInfo cecDeviceInfo) {
+    public String onHdmiCecDeviceRemoved(HdmiDeviceInfo cecDeviceInfo) {
         return null;
     }
 
     /**
-     * Notify wrapped TV input ID of current input to TV input framework manager
-     *
-     * @param inputId The TV input ID of {@link TvInputPassthroughWrapperService}
-     * @param wrappedInputId The ID of the wrapped TV input such as external pass-though TV input
-     * @hide
-     */
-    public final void notifyWrappedInputId(String inputId, String wrappedInputId) {
-        SomeArgs args = SomeArgs.obtain();
-        args.arg1 = inputId;
-        args.arg2 = wrappedInputId;
-        mHandler.obtainMessage(TvInputService.ServiceHandler.DO_SET_WRAPPED_TV_INPUT_ID,
-                args).sendToTarget();
-    }
-
-    /**
      * Base class for derived classes to implement to provide a TV input session.
      */
-    public abstract class Session implements KeyEvent.Callback {
+    public abstract static class Session implements KeyEvent.Callback {
         private final KeyEvent.DispatcherState mDispatcherState = new KeyEvent.DispatcherState();
         private final WindowManager mWindowManager;
+        final Handler mHandler;
         private WindowManager.LayoutParams mWindowParams;
         private Surface mSurface;
         private View mOverlayView;
@@ -245,8 +242,14 @@
         private Rect mOverlayFrame;
         private ITvInputSessionCallback mSessionCallback;
 
-        public Session() {
-            mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
+        /**
+         * Creates a new Session.
+         *
+         * @param context The context of the application
+         */
+        public Session(Context context) {
+            mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+            mHandler = new Handler(context.getMainLooper());
         }
 
         /**
@@ -319,42 +322,56 @@
         }
 
         /**
-         * Sends the change on the track information. This is expected to be called whenever a
-         * track is added/removed and the metadata of a track is modified.
+         * Sends the change on the track information. This is expected to be called whenever a track
+         * is added/removed and the metadata of a track is modified.
          *
          * @param tracks A list which includes track information.
+         * @throws IllegalArgumentException if {@code tracks} contains redundant tracks.
          */
-        public void notifyTrackInfoChanged(final List<TvTrackInfo> tracks) {
+        public void notifyTracksChanged(final List<TvTrackInfo> tracks) {
+            Set<String> trackIdSet = new HashSet<String>();
+            for (TvTrackInfo track : tracks) {
+                String trackId = track.getId();
+                if (trackIdSet.contains(trackId)) {
+                    throw new IllegalArgumentException("redundant track ID: " + trackId);
+                }
+                trackIdSet.add(trackId);
+            }
+            trackIdSet.clear();
+
+            // TODO: Validate the track list.
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
                     try {
-                        if (DEBUG) Log.d(TAG, "notifyTrackInfoChanged");
-                        mSessionCallback.onTrackInfoChanged(tracks);
+                        if (DEBUG) Log.d(TAG, "notifyTracksChanged");
+                        mSessionCallback.onTracksChanged(tracks);
                     } catch (RemoteException e) {
-                        Log.w(TAG, "error in notifyTrackInfoChanged");
+                        Log.w(TAG, "error in notifyTracksChanged");
                     }
                 }
             });
         }
 
         /**
-         * Sends the list of selected tracks. This is expected to be called whenever there is a
-         * change on track selection.
+         * Sends the ID of the selected track for a given track type. This is expected to be called
+         * whenever there is a change on track selection.
          *
-         * @param selectedTracks A list of selected tracks.
-         * @see #onSelectTrack(TvTrackInfo)
-         * @see #onUnselectTrack(TvTrackInfo)
+         * @param type The type of the selected track. The type can be
+         *            {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or
+         *            {@link TvTrackInfo#TYPE_SUBTITLE}.
+         * @param trackId The ID of the selected track.
+         * @see #onSelectTrack
          */
-        public void notifyTrackSelectionChanged(final List<TvTrackInfo> selectedTracks) {
+        public void notifyTrackSelected(final int type, final String trackId) {
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
                     try {
-                        if (DEBUG) Log.d(TAG, "notifyTrackSelectionChanged");
-                        mSessionCallback.onTrackSelectionChanged(selectedTracks);
+                        if (DEBUG) Log.d(TAG, "notifyTrackSelected");
+                        mSessionCallback.onTrackSelected(type, trackId);
                     } catch (RemoteException e) {
-                        Log.w(TAG, "error in notifyTrackSelectionChanged");
+                        Log.w(TAG, "error in notifyTrackSelected");
                     }
                 }
             });
@@ -382,7 +399,7 @@
          * Informs the application that video is not available, so the TV input cannot continue
          * playing the TV stream.
          *
-         * @param reason The reason why the TV input stopped the playback:
+         * @param reason The reason that the TV input stopped the playback:
          * <ul>
          * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_UNKNOWN}
          * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_TUNING}
@@ -488,6 +505,35 @@
         }
 
         /**
+         * Assigns a position of the {@link Surface} passed by {@link #onSetSurface}. The position
+         * is relative to an overlay view. {@see #onOverlayViewSizeChanged}.
+         *
+         * @param left Left position in pixels, relative to the overlay view.
+         * @param top Top position in pixels, relative to the overlay view.
+         * @param right Right position in pixels, relative to the overlay view.
+         * @param bottm Bottom position in pixels, relative to the overlay view.
+         * @hide
+         */
+        @SystemApi
+        public void layoutSurface(final int left, final int top, final int right, final int bottm) {
+            if (left > right || top > bottm) {
+                throw new IllegalArgumentException("Invalid parameter");
+            }
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "layoutSurface (l=" + left + ", t=" + top + ", r="
+                                + right + ", b=" + bottm + ",)");
+                        mSessionCallback.onLayoutSurface(left, top, right, bottm);
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in layoutSurface");
+                    }
+                }
+            });
+        }
+
+        /**
          * Called when the session is released.
          */
         public abstract void onRelease();
@@ -540,6 +586,20 @@
         }
 
         /**
+         * Called when a size of an overlay view is changed by an application. Even when the overlay
+         * view is disabled by {@link #setOverlayViewEnabled}, this is called. The size is same as
+         * the size of {@link Surface} in general. Once {@link #layoutSurface} is called, the sizes
+         * of {@link Surface} and the overlay view can be different.
+         *
+         * @param width The width of the overlay view.
+         * @param height The height of the overlay view.
+         * @hide
+         */
+        @SystemApi
+        public void onOverlayViewSizeChanged(int width, int height) {
+        }
+
+        /**
          * Sets the relative stream volume of the current TV input session to handle the change of
          * audio focus by setting.
          *
@@ -598,34 +658,20 @@
         }
 
         /**
-         * Selects a given track.
+         * Select a given track.
          * <p>
-         * If it is called multiple times on the same type of track (ie. Video, Audio, Text), the
-         * track selected previously should be unselected in the implementation of this method.
-         * Also, if the select operation was successful, the implementation should call
-         * {@link #notifyTrackSelectionChanged(List)} to report the selected track list.
+         * If this is done successfully, the implementation should call {@link #notifyTrackSelected}
+         * to help applications maintain the selcted track lists.
          * </p>
          *
-         * @param track The track to be selected.
-         * @return {@code true} if the select operation was successful, {@code false} otherwise.
-         * @see #notifyTrackSelectionChanged(List)
+         * @param trackId The ID of the track to select. {@code null} means to unselect the current
+         *            track for a given type.
+         * @param type The type of the track to select. The type can be
+         *            {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or
+         *            {@link TvTrackInfo#TYPE_SUBTITLE}.
+         * @see #notifyTrackSelected
          */
-        public boolean onSelectTrack(TvTrackInfo track) {
-            return false;
-        }
-
-        /**
-         * Unselects a given track.
-         * <p>
-         * If the unselect operation was successful, the implementation should call
-         * {@link #notifyTrackSelectionChanged(List)} to report the selected track list.
-         * </p>
-         *
-         * @param track The track to be unselected.
-         * @return {@code true} if the unselect operation was successful, {@code false} otherwise.
-         * @see #notifyTrackSelectionChanged(List)
-         */
-        public boolean onUnselectTrack(TvTrackInfo track) {
+        public boolean onSelectTrack(int type, String trackId) {
             return false;
         }
 
@@ -837,17 +883,8 @@
         /**
          * Calls {@link #onSelectTrack}.
          */
-        void selectTrack(TvTrackInfo track) {
-            onSelectTrack(track);
-            // TODO: Handle failure.
-        }
-
-        /**
-         * Calls {@link #onUnselectTrack}.
-         */
-        void unselectTrack(TvTrackInfo track) {
-            onUnselectTrack(track);
-            // TODO: Handle failure.
+        void selectTrack(int type, String trackId) {
+            onSelectTrack(type, trackId);
         }
 
         /**
@@ -880,6 +917,7 @@
             if (DEBUG) Log.d(TAG, "create overlay view(" + frame + ")");
             mWindowToken = windowToken;
             mOverlayFrame = frame;
+            onOverlayViewSizeChanged(frame.right - frame.left, frame.bottom - frame.top);
             if (!mOverlayViewEnabled) {
                 return;
             }
@@ -894,7 +932,7 @@
             // the application that owns the window token can decide whether to consume or
             // dispatch the input events.
             int flag = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                     | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
             mWindowParams = new WindowManager.LayoutParams(
                     frame.right - frame.left, frame.bottom - frame.top,
@@ -913,6 +951,12 @@
          */
         void relayoutOverlayView(Rect frame) {
             if (DEBUG) Log.d(TAG, "relayoutOverlayView(" + frame + ")");
+            if (mOverlayFrame == null || mOverlayFrame.width() != frame.width()
+                    || mOverlayFrame.height() != frame.height()) {
+                // Note: relayoutOverlayView is called whenever TvView's layout is changed
+                // regardless of setOverlayViewEnabled.
+                onOverlayViewSizeChanged(frame.right - frame.left, frame.bottom - frame.top);
+            }
             mOverlayFrame = frame;
             if (!mOverlayViewEnabled || mOverlayView == null) {
                 return;
@@ -994,6 +1038,106 @@
         }
     }
 
+    /**
+     * Base class for a TV input session which represents an external device connected to a
+     * hardware TV input. Once TV input returns an implementation of this class on
+     * {@link #onCreateSession(String)}, the framework will create a hardware session and forward
+     * the application's surface to the hardware TV input.
+     * @see #onCreateSession(String)
+     */
+    public abstract static class HardwareSession extends Session {
+
+        /**
+         * Creates a new HardwareSession.
+         *
+         * @param context The context of the application
+         */
+        public HardwareSession(Context context) {
+            super(context);
+        }
+
+        private TvInputManager.Session mHardwareSession;
+        private ITvInputSession mProxySession;
+        private ITvInputSessionCallback mProxySessionCallback;
+
+        /**
+         * Returns the hardware TV input ID the external device is connected to.
+         * <p>
+         * TV input is expected to provide {@link android.R.attr#setupActivity} so that
+         * the application can launch it before using this TV input. The setup activity may let
+         * the user select the hardware TV input to which the external device is connected. The ID
+         * of the selected one should be stored in the TV input so that it can be returned here.
+         * </p>
+         */
+        public abstract String getHardwareInputId();
+
+        private final TvInputManager.SessionCallback mHardwareSessionCallback =
+                new TvInputManager.SessionCallback() {
+            @Override
+            public void onSessionCreated(TvInputManager.Session session) {
+                mHardwareSession = session;
+                SomeArgs args = SomeArgs.obtain();
+                if (session != null) {
+                    args.arg1 = mProxySession;
+                    args.arg2 = mProxySessionCallback;
+                    args.arg3 = session.getToken();
+                } else {
+                    args.arg1 = null;
+                    args.arg2 = mProxySessionCallback;
+                    args.arg3 = null;
+                    onRelease();
+                }
+                mHandler.obtainMessage(ServiceHandler.DO_NOTIFY_SESSION_CREATED, args)
+                        .sendToTarget();
+            }
+
+            @Override
+            public void onVideoAvailable(final TvInputManager.Session session) {
+                if (mHardwareSession == session) {
+                    onHardwareVideoAvailable();
+                }
+            }
+
+            @Override
+            public void onVideoUnavailable(final TvInputManager.Session session,
+                    final int reason) {
+                if (mHardwareSession == session) {
+                    onHardwareVideoUnavailable(reason);
+                }
+            }
+        };
+
+        /**
+         * This method will not be called in {@link HardwareSession}. Framework will
+         * forward the application's surface to the hardware TV input.
+         */
+        @Override
+        public final boolean onSetSurface(Surface surface) {
+            Log.e(TAG, "onSetSurface() should not be called in HardwareProxySession.");
+            return false;
+        }
+
+        /**
+         * Called when the underlying hardware TV input session calls
+         * {@link TvInputService.Session#notifyVideoAvailable()}.
+         */
+        public void onHardwareVideoAvailable() { }
+
+        /**
+         * Called when the underlying hardware TV input session calls
+         * {@link TvInputService.Session#notifyVideoUnavailable(int)}.
+         *
+         * @param reason The reason that the hardware TV input stopped the playback:
+         * <ul>
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_UNKNOWN}
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_TUNING}
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL}
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_BUFFERING}
+         * </ul>
+         */
+        public void onHardwareVideoUnavailable(int reason) { }
+    }
+
     /** @hide */
     public static boolean isNavigationKey(int keyCode) {
         switch (keyCode) {
@@ -1017,11 +1161,11 @@
     @SuppressLint("HandlerLeak")
     private final class ServiceHandler extends Handler {
         private static final int DO_CREATE_SESSION = 1;
-        private static final int DO_ADD_HARDWARE_TV_INPUT = 2;
-        private static final int DO_REMOVE_HARDWARE_TV_INPUT = 3;
-        private static final int DO_ADD_HDMI_CEC_TV_INPUT = 4;
-        private static final int DO_REMOVE_HDMI_CEC_TV_INPUT = 5;
-        private static final int DO_SET_WRAPPED_TV_INPUT_ID = 6;
+        private static final int DO_NOTIFY_SESSION_CREATED = 2;
+        private static final int DO_ADD_HARDWARE_TV_INPUT = 3;
+        private static final int DO_REMOVE_HARDWARE_TV_INPUT = 4;
+        private static final int DO_ADD_HDMI_CEC_TV_INPUT = 5;
+        private static final int DO_REMOVE_HDMI_CEC_TV_INPUT = 6;
 
         private void broadcastAddHardwareTvInput(int deviceId, TvInputInfo inputInfo) {
             int n = mCallbacks.beginBroadcast();
@@ -1060,18 +1204,6 @@
             mCallbacks.finishBroadcast();
         }
 
-        private void broadcastSetWrappedTvInputId(String inputId, String wrappedInputId) {
-            int n = mCallbacks.beginBroadcast();
-            for (int i = 0; i < n; ++i) {
-                try {
-                    mCallbacks.getBroadcastItem(i).setWrappedInputId(inputId, wrappedInputId);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Error while broadcasting.", e);
-                }
-            }
-            mCallbacks.finishBroadcast();
-        }
-
         @Override
         public final void handleMessage(Message msg) {
             switch (msg.what) {
@@ -1080,17 +1212,58 @@
                     InputChannel channel = (InputChannel) args.arg1;
                     ITvInputSessionCallback cb = (ITvInputSessionCallback) args.arg2;
                     String inputId = (String) args.arg3;
-                    try {
-                        Session sessionImpl = onCreateSession(inputId);
-                        if (sessionImpl == null) {
+                    Session sessionImpl = onCreateSession(inputId);
+                    args.recycle();
+                    if (sessionImpl == null) {
+                        try {
                             // Failed to create a session.
-                            cb.onSessionCreated(null);
-                        } else {
-                            sessionImpl.setSessionCallback(cb);
-                            ITvInputSession stub = new ITvInputSessionWrapper(TvInputService.this,
-                                    sessionImpl, channel);
-                            cb.onSessionCreated(stub);
+                            cb.onSessionCreated(null, null);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "error in onSessionCreated");
                         }
+                    } else {
+                        sessionImpl.setSessionCallback(cb);
+                        ITvInputSession stub = new ITvInputSessionWrapper(TvInputService.this,
+                                sessionImpl, channel);
+                        if (sessionImpl instanceof HardwareSession) {
+                            HardwareSession proxySession =
+                                    ((HardwareSession) sessionImpl);
+                            String harewareInputId = proxySession.getHardwareInputId();
+                            if (!TextUtils.isEmpty(harewareInputId)) {
+                                // TODO: check if the given ID is really hardware TV input.
+                                proxySession.mProxySession = stub;
+                                proxySession.mProxySessionCallback = cb;
+                                TvInputManager manager = (TvInputManager) getSystemService(
+                                        Context.TV_INPUT_SERVICE);
+                                manager.createSession(harewareInputId,
+                                        proxySession.mHardwareSessionCallback, mServiceHandler);
+                            } else {
+                                sessionImpl.onRelease();
+                                Log.w(TAG, "Hardware input id is not setup yet.");
+                                try {
+                                    cb.onSessionCreated(null, null);
+                                } catch (RemoteException e) {
+                                    Log.e(TAG, "error in onSessionCreated");
+                                }
+                            }
+                        } else {
+                            SomeArgs someArgs = SomeArgs.obtain();
+                            someArgs.arg1 = stub;
+                            someArgs.arg2 = cb;
+                            someArgs.arg3 = null;
+                            mServiceHandler.obtainMessage(ServiceHandler.DO_NOTIFY_SESSION_CREATED,
+                                    someArgs).sendToTarget();
+                        }
+                    }
+                    return;
+                }
+                case DO_NOTIFY_SESSION_CREATED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    ITvInputSession stub = (ITvInputSession) args.arg1;
+                    ITvInputSessionCallback cb = (ITvInputSessionCallback) args.arg2;
+                    IBinder hardwareSessionToken = (IBinder) args.arg3;
+                    try {
+                        cb.onSessionCreated(stub, hardwareSessionToken);
                     } catch (RemoteException e) {
                         Log.e(TAG, "error in onSessionCreated");
                     }
@@ -1114,7 +1287,7 @@
                     return;
                 }
                 case DO_ADD_HDMI_CEC_TV_INPUT: {
-                    HdmiCecDeviceInfo cecDeviceInfo = (HdmiCecDeviceInfo) msg.obj;
+                    HdmiDeviceInfo cecDeviceInfo = (HdmiDeviceInfo) msg.obj;
                     TvInputInfo inputInfo = onHdmiCecDeviceAdded(cecDeviceInfo);
                     if (inputInfo != null) {
                         broadcastAddHdmiCecTvInput(cecDeviceInfo.getLogicalAddress(), inputInfo);
@@ -1122,20 +1295,13 @@
                     return;
                 }
                 case DO_REMOVE_HDMI_CEC_TV_INPUT: {
-                    HdmiCecDeviceInfo cecDeviceInfo = (HdmiCecDeviceInfo) msg.obj;
+                    HdmiDeviceInfo cecDeviceInfo = (HdmiDeviceInfo) msg.obj;
                     String inputId = onHdmiCecDeviceRemoved(cecDeviceInfo);
                     if (inputId != null) {
                         broadcastRemoveTvInput(inputId);
                     }
                     return;
                 }
-                case DO_SET_WRAPPED_TV_INPUT_ID: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    String inputId = (String) args.arg1;
-                    String wrappedInputId = (String) args.arg2;
-                    broadcastSetWrappedTvInputId(inputId, wrappedInputId);
-                    return;
-                }
                 default: {
                     Log.w(TAG, "Unhandled message code: " + msg.what);
                     return;
diff --git a/media/java/android/media/tv/TvTrackInfo.java b/media/java/android/media/tv/TvTrackInfo.java
index 3b80db4..6ddb2a2 100644
--- a/media/java/android/media/tv/TvTrackInfo.java
+++ b/media/java/android/media/tv/TvTrackInfo.java
@@ -40,6 +40,7 @@
     public static final int TYPE_SUBTITLE = 2;
 
     private final int mType;
+    private final String mId;
     private final String mLanguage;
     private final int mAudioChannelCount;
     private final int mAudioSampleRate;
@@ -47,9 +48,10 @@
     private final int mVideoHeight;
     private final Bundle mExtra;
 
-    private TvTrackInfo(int type, String language, int audioChannelCount,
+    private TvTrackInfo(int type, String id, String language, int audioChannelCount,
             int audioSampleRate, int videoWidth, int videoHeight, Bundle extra) {
         mType = type;
+        mId = id;
         mLanguage = language;
         mAudioChannelCount = audioChannelCount;
         mAudioSampleRate = audioSampleRate;
@@ -60,6 +62,7 @@
 
     private TvTrackInfo(Parcel in) {
         mType = in.readInt();
+        mId = in.readString();
         mLanguage = in.readString();
         mAudioChannelCount = in.readInt();
         mAudioSampleRate = in.readInt();
@@ -77,6 +80,13 @@
     }
 
     /**
+     * Returns the ID of the track.
+     */
+    public final String getId() {
+        return mId;
+    }
+
+    /**
      * Returns the language information encoded by either ISO 639-1 or ISO 639-2/T. If the language
      * is unknown or could not be determined, the corresponding value will be {@code null}.
      */
@@ -85,7 +95,7 @@
     }
 
     /**
-     * Returns the audio channel count. Valid for {@link #TYPE_AUDIO} tracks only.
+     * Returns the audio channel count. Valid only for {@link #TYPE_AUDIO} tracks.
      */
     public final int getAudioChannelCount() {
         if (mType != TYPE_AUDIO) {
@@ -95,7 +105,7 @@
     }
 
     /**
-     * Returns the audio sample rate, in the unit of Hz. Valid for {@link #TYPE_AUDIO} tracks only.
+     * Returns the audio sample rate, in the unit of Hz. Valid only for {@link #TYPE_AUDIO} tracks.
      */
     public final int getAudioSampleRate() {
         if (mType != TYPE_AUDIO) {
@@ -105,8 +115,8 @@
     }
 
     /**
-     * Returns the width of the video, in the unit of pixels. Valid for {@link #TYPE_VIDEO} tracks
-     * only.
+     * Returns the width of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
+     * tracks.
      */
     public final int getVideoWidth() {
         if (mType != TYPE_VIDEO) {
@@ -116,8 +126,8 @@
     }
 
     /**
-     * Returns the height of the video, in the unit of pixels. Valid for {@link #TYPE_VIDEO} tracks
-     * only.
+     * Returns the height of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
+     * tracks.
      */
     public final int getVideoHeight() {
         if (mType != TYPE_VIDEO) {
@@ -147,6 +157,7 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(mType);
+        dest.writeString(mId);
         dest.writeString(mLanguage);
         dest.writeInt(mAudioChannelCount);
         dest.writeInt(mAudioSampleRate);
@@ -172,7 +183,8 @@
      * A builder class for creating {@link TvTrackInfo} objects.
      */
     public static final class Builder {
-        private int mType;
+        private final String mId;
+        private final int mType;
         private String mLanguage;
         private int mAudioChannelCount;
         private int mAudioSampleRate;
@@ -185,14 +197,20 @@
          * must be added.
          *
          * @param type The type of the track.
+         * @param id The ID of the track that uniquely identifies the current track among all the
+         *            other tracks in the same TV program.
          */
-        public Builder(int type) {
+        public Builder(int type, String id) {
             if (type != TYPE_AUDIO
                     && type != TYPE_VIDEO
                     && type != TYPE_SUBTITLE) {
                 throw new IllegalArgumentException("Unknown type: " + type);
             }
+            if (id == null) {
+                throw new IllegalArgumentException("id cannot be null");
+            }
             mType = type;
+            mId = id;
         }
 
         /**
@@ -206,7 +224,7 @@
         }
 
         /**
-         * Sets the audio channel count. Valid for {@link #TYPE_AUDIO} tracks only.
+         * Sets the audio channel count. Valid only for {@link #TYPE_AUDIO} tracks.
          *
          * @param audioChannelCount The audio channel count.
          */
@@ -219,7 +237,8 @@
         }
 
         /**
-         * Sets the audio sample rate, in the unit of Hz. Valid for {@link #TYPE_AUDIO} tracks only.
+         * Sets the audio sample rate, in the unit of Hz. Valid only for {@link #TYPE_AUDIO}
+         * tracks.
          *
          * @param audioSampleRate The audio sample rate.
          */
@@ -232,8 +251,8 @@
         }
 
         /**
-         * Sets the width of the video, in the unit of pixels. Valid for {@link #TYPE_VIDEO} tracks
-         * only.
+         * Sets the width of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
+         * tracks.
          *
          * @param videoWidth The width of the video.
          */
@@ -246,8 +265,8 @@
         }
 
         /**
-         * Sets the height of the video, in the unit of pixels. Valid for {@link #TYPE_VIDEO} tracks
-         * only.
+         * Sets the height of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
+         * tracks.
          *
          * @param videoHeight The height of the video.
          */
@@ -275,8 +294,8 @@
          * @return The new {@link TvTrackInfo} instance
          */
         public TvTrackInfo build() {
-            return new TvTrackInfo(mType, mLanguage, mAudioChannelCount,
-                    mAudioSampleRate, mVideoWidth, mVideoHeight, mExtra);
+            return new TvTrackInfo(mType, mId, mLanguage, mAudioChannelCount, mAudioSampleRate,
+                    mVideoWidth, mVideoHeight, mExtra);
         }
     }
 }
\ No newline at end of file
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 2696a63..591f543 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -41,7 +41,18 @@
 import java.util.List;
 
 /**
- * View playing TV
+ * Displays TV contents. The TvView class provides a high level interface for applications to show
+ * TV programs from various TV sources that implement {@link TvInputService}. (Note that the list of
+ * TV inputs available on the system can be obtained by calling
+ * {@link TvInputManager#getTvInputList() TvInputManager.getTvInputList()}.)
+ * <p>
+ * Once the application supplies the URI for a specific TV channel to {@link #tune(String, Uri)}
+ * method, it takes care of underlying service binding (and unbinding if the current TvView is
+ * already bound to a service) and automatically allocates/deallocates resources needed. In addition
+ * to a few essential methods to control how the contents are presented, it also provides a way to
+ * dispatch input events to the connected TvInputService in order to enable custom key actions for
+ * the TV input.
+ * </p>
  */
 public class TvView extends ViewGroup {
     private static final String TAG = "TvView";
@@ -63,6 +74,14 @@
 
     private static final int VIDEO_SIZE_VALUE_UNKNOWN = 0;
 
+    private static final int ZORDER_MEDIA = 0;
+    private static final int ZORDER_MEDIA_OVERLAY = 1;
+    private static final int ZORDER_ON_TOP = 2;
+
+    private static final int CAPTION_DEFAULT = 0;
+    private static final int CAPTION_ENABLED = 1;
+    private static final int CAPTION_DISABLED = 2;
+
     private static final Object sMainTvViewLock = new Object();
     private static TvView sMainTvView;
 
@@ -86,6 +105,13 @@
     private int mSurfaceHeight;
     private final AttributeSet mAttrs;
     private final int mDefStyleAttr;
+    private int mWindowZOrder;
+    private boolean mUseRequestedSurfaceLayout;
+    private int mSurfaceViewLeft;
+    private int mSurfaceViewRight;
+    private int mSurfaceViewTop;
+    private int mSurfaceViewBottom;
+    private int mCaptionEnabled;
 
     private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
         @Override
@@ -162,7 +188,7 @@
     }
 
     /**
-     * Set this as main TvView.
+     * Sets this as main TvView.
      * <p>
      * Main TvView is the TvView which user is watching and interacting mainly.  It is used for
      * determining internal behavior of hardware TV input devices. For example, this influences
@@ -185,6 +211,51 @@
     }
 
     /**
+     * Sets the Z order of a window owning the surface of this TvView above the normal TvView
+     * but below an application.
+     *
+     * @see SurfaceView#setZOrderMediaOverlay
+     * @hide
+     */
+    @SystemApi
+    public void setZOrderMediaOverlay(boolean isMediaOverlay) {
+        if (isMediaOverlay) {
+            mWindowZOrder = ZORDER_MEDIA_OVERLAY;
+            removeSessionOverlayView();
+        } else {
+            mWindowZOrder = ZORDER_MEDIA;
+            createSessionOverlayView();
+        }
+        if (mSurfaceView != null) {
+            // ZOrderOnTop(false) removes WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+            // from WindowLayoutParam as well as changes window type.
+            mSurfaceView.setZOrderOnTop(false);
+            mSurfaceView.setZOrderMediaOverlay(isMediaOverlay);
+        }
+    }
+
+    /**
+     * Sets the Z order of a window owning the surface of this TvView on top of an application.
+     *
+     * @see SurfaceView#setZOrderOnTop
+     * @hide
+     */
+    @SystemApi
+    public void setZOrderOnTop(boolean onTop) {
+        if (onTop) {
+            mWindowZOrder = ZORDER_ON_TOP;
+            removeSessionOverlayView();
+        } else {
+            mWindowZOrder = ZORDER_MEDIA;
+            createSessionOverlayView();
+        }
+        if (mSurfaceView != null) {
+            mSurfaceView.setZOrderMediaOverlay(false);
+            mSurfaceView.setZOrderOnTop(onTop);
+        }
+     }
+
+    /**
      * Sets the relative stream volume of this session to handle a change of audio focus.
      *
      * @param volume A volume value between 0.0f to 1.0f.
@@ -203,7 +274,7 @@
     /**
      * Tunes to a given channel.
      *
-     * @param inputId The id of TV input which will play the given channel.
+     * @param inputId The ID of TV input which will play the given channel.
      * @param channelUri The URI of a channel.
      */
     public void tune(String inputId, Uri channelUri) {
@@ -213,7 +284,7 @@
     /**
      * Tunes to a given channel.
      *
-     * @param inputId The id of TV input which will play the given channel.
+     * @param inputId The ID of TV input which will play the given channel.
      * @param channelUri The URI of a channel.
      * @param params Extra parameters which might be handled with the tune event.
      * @hide
@@ -287,66 +358,61 @@
      * @param enabled {@code true} to enable, {@code false} to disable.
      */
     public void setCaptionEnabled(boolean enabled) {
+        mCaptionEnabled = enabled ? CAPTION_ENABLED : CAPTION_DISABLED;
         if (mSession != null) {
             mSession.setCaptionEnabled(enabled);
         }
     }
 
     /**
-     * Select a track.
-     * <p>
-     * If it is called multiple times on the same type of track (ie. Video, Audio, Text), the track
-     * selected in previous will be unselected. Note that this method does not take any effect
-     * unless the current TvView is tuned.
-     * </p>
+     * Selects a track.
      *
-     * @param track the track to be selected.
-     * @see #getTracks()
+     * @param type The type of the track to select. The type can be {@link TvTrackInfo#TYPE_AUDIO},
+     *            {@link TvTrackInfo#TYPE_VIDEO} or {@link TvTrackInfo#TYPE_SUBTITLE}.
+     * @param trackId The ID of the track to select. {@code null} means to unselect the current
+     *            track for a given type.
+     * @see #getTracks
+     * @see #getSelectedTrack
      */
-    public void selectTrack(TvTrackInfo track) {
+    public void selectTrack(int type, String trackId) {
         if (mSession != null) {
-            mSession.selectTrack(track);
+            mSession.selectTrack(type, trackId);
         }
     }
 
     /**
-     * Unselect a track.
-     * <p>
-     * Note that this method does not take any effect unless the current TvView is tuned.
+     * Returns the list of tracks. Returns {@code null} if the information is not available.
      *
-     * @param track the track to be unselected.
-     * @see #getTracks()
+     * @param type The type of the tracks. The type can be {@link TvTrackInfo#TYPE_AUDIO},
+     *            {@link TvTrackInfo#TYPE_VIDEO} or {@link TvTrackInfo#TYPE_SUBTITLE}.
+     * @see #selectTrack
+     * @see #getSelectedTrack
      */
-    public void unselectTrack(TvTrackInfo track) {
-        if (mSession != null) {
-            mSession.unselectTrack(track);
-        }
-    }
-
-    /**
-     * Returns a list which includes of track information. May return {@code null} if the
-     * information is not available.
-     */
-    public List<TvTrackInfo> getTracks() {
+    public List<TvTrackInfo> getTracks(int type) {
         if (mSession == null) {
             return null;
         }
-        return mSession.getTracks();
+        return mSession.getTracks(type);
     }
 
     /**
-     * Returns a list of selected tracks. May return {@code null} if the information is not
-     * available.
+     * Returns the ID of the selected track for a given type. Returns {@code null} if the
+     * information is not available or the track is not selected.
+     *
+     * @param type The type of the selected tracks. The type can be {@link TvTrackInfo#TYPE_AUDIO},
+     *            {@link TvTrackInfo#TYPE_VIDEO} or {@link TvTrackInfo#TYPE_SUBTITLE}.
+     * @see #selectTrack
+     * @see #getTracks
      */
-    public List<TvTrackInfo> getSelectedTracks() {
+    public String getSelectedTrack(int type) {
         if (mSession == null) {
             return null;
         }
-        return mSession.getSelectedTracks();
+        return mSession.getSelectedTrack(type);
     }
 
     /**
-     * Call {@link TvInputService.Session#appPrivateCommand(String, Bundle)
+     * Calls {@link TvInputService.Session#appPrivateCommand(String, Bundle)
      * TvInputService.Session.appPrivateCommand()} on the current TvView.
      *
      * @param action Name of the command to be performed. This <em>must</em> be a scoped name, i.e.
@@ -385,8 +451,8 @@
     }
 
     /**
-     * Called when an unhandled input event was also not handled by the user provided callback. This
-     * is the last chance to handle the unhandled input event in the TvView.
+     * Called when an unhandled input event also has not been handled by the user provided
+     * callback. This is the last chance to handle the unhandled input event in the TvView.
      *
      * @param event The input event.
      * @return If you handled the event, return {@code true}. If you want to allow the event to be
@@ -397,9 +463,9 @@
     }
 
     /**
-     * Registers a callback to be invoked when an input event was not handled by the bound TV input.
+     * Registers a callback to be invoked when an input event is not handled by the bound TV input.
      *
-     * @param listener The callback to invoke when the unhandled input event was received.
+     * @param listener The callback to be invoked when the unhandled input event is received.
      */
     public void setOnUnhandledInputEventListener(OnUnhandledInputEventListener listener) {
         mOnUnhandledInputEventListener = listener;
@@ -491,7 +557,16 @@
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        mSurfaceView.layout(0, 0, right - left, bottom - top);
+        if (DEBUG) {
+            Log.d(TAG, "onLayout (left=" + left + ", top=" + top + ", right=" + right
+                    + ", bottom=" + bottom + ",)");
+        }
+        if (mUseRequestedSurfaceLayout) {
+            mSurfaceView.layout(mSurfaceViewLeft, mSurfaceViewTop, mSurfaceViewRight,
+                    mSurfaceViewBottom);
+        } else {
+            mSurfaceView.layout(0, 0, right - left, bottom - top);
+        }
     }
 
     @Override
@@ -528,12 +603,18 @@
                 relayoutSessionOverlayView();
             }};
         mSurfaceView.getHolder().addCallback(mSurfaceHolderCallback);
+        if (mWindowZOrder == ZORDER_MEDIA_OVERLAY) {
+            mSurfaceView.setZOrderMediaOverlay(true);
+        } else if (mWindowZOrder == ZORDER_ON_TOP) {
+            mSurfaceView.setZOrderOnTop(true);
+        }
         addView(mSurfaceView);
     }
 
     private void release() {
         setSessionSurface(null);
         removeSessionOverlayView();
+        mUseRequestedSurfaceLayout = false;
         mSession.release();
         mSession = null;
         mSessionCallback = null;
@@ -555,7 +636,7 @@
 
     private void createSessionOverlayView() {
         if (mSession == null || !isAttachedToWindow()
-                || mOverlayViewCreated) {
+                || mOverlayViewCreated || mWindowZOrder != ZORDER_MEDIA) {
             return;
         }
         mOverlayViewFrame = getViewFrameOnScreen();
@@ -573,8 +654,8 @@
     }
 
     private void relayoutSessionOverlayView() {
-        if (mSession == null || !isAttachedToWindow()
-                || !mOverlayViewCreated) {
+        if (mSession == null || !isAttachedToWindow() || !mOverlayViewCreated
+                || mWindowZOrder != ZORDER_MEDIA) {
             return;
         }
         Rect viewFrame = getViewFrameOnScreen();
@@ -592,22 +673,6 @@
                 location[0] + getWidth(), location[1] + getHeight());
     }
 
-    private void updateVideoSize(List<TvTrackInfo> tracks) {
-        for (TvTrackInfo track : tracks) {
-            if (track.getType() == TvTrackInfo.TYPE_VIDEO) {
-                int width = track.getVideoWidth();
-                int height = track.getVideoHeight();
-                if (width != mVideoWidth || height != mVideoHeight) {
-                    mVideoWidth = width;
-                    mVideoHeight = height;
-                    if (mListener != null) {
-                        mListener.onVideoSizeChanged(mSessionCallback.mInputId, width, height);
-                    }
-                }
-            }
-        }
-    }
-
     /**
      * Interface used to receive various status updates on the {@link TvView}.
      */
@@ -650,16 +715,19 @@
          * @param inputId The ID of the TV input bound to this view.
          * @param tracks A list which includes track information.
          */
-        public void onTrackInfoChanged(String inputId, List<TvTrackInfo> tracks) {
+        public void onTracksChanged(String inputId, List<TvTrackInfo> tracks) {
         }
 
         /**
          * This is called when there is a change on the selected tracks.
          *
          * @param inputId The ID of the TV input bound to this view.
-         * @param selectedTracks A list which includes track information.
+         * @param type The type of the track selected. The type can be
+         *            {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or
+         *            {@link TvTrackInfo#TYPE_SUBTITLE}.
+         * @param trackId The ID of the track selected.
          */
-        public void onTrackSelectionChanged(String inputId, List<TvTrackInfo> selectedTracks) {
+        public void onTrackSelected(String inputId, int type, String trackId) {
         }
 
         /**
@@ -770,6 +838,9 @@
                     }
                 }
                 createSessionOverlayView();
+                if (mCaptionEnabled != CAPTION_DEFAULT) {
+                    mSession.setCaptionEnabled(mCaptionEnabled == CAPTION_ENABLED);
+                }
                 mSession.tune(mChannelUri, mTuneParams);
                 if (mHasStreamVolume) {
                     mSession.setStreamVolume(mStreamVolume);
@@ -807,29 +878,29 @@
         }
 
         @Override
-        public void onTrackInfoChanged(Session session, List<TvTrackInfo> tracks) {
+        public void onTracksChanged(Session session, List<TvTrackInfo> tracks) {
             if (this != mSessionCallback) {
                 return;
             }
             if (DEBUG) {
-                Log.d(TAG, "onTrackInfoChanged()");
+                Log.d(TAG, "onTracksChanged()");
             }
             if (mListener != null) {
-                mListener.onTrackInfoChanged(mInputId, tracks);
+                mListener.onTracksChanged(mInputId, tracks);
             }
         }
 
         @Override
-        public void onTrackSelectionChanged(Session session, List<TvTrackInfo> selectedTracks) {
+        public void onTrackSelected(Session session, int type, String trackId) {
             if (this != mSessionCallback) {
                 return;
             }
             if (DEBUG) {
-                Log.d(TAG, "onTrackInfoChanged()");
+                Log.d(TAG, "onTrackSelected()");
             }
-            updateVideoSize(selectedTracks);
+            // TODO: Update the video size when the type is TYPE_VIDEO.
             if (mListener != null) {
-                mListener.onTrackSelectionChanged(mInputId, selectedTracks);
+                mListener.onTrackSelected(mInputId, type, trackId);
             }
         }
 
@@ -883,6 +954,20 @@
         }
 
         @Override
+        public void onLayoutSurface(Session session, int left, int top, int right, int bottom) {
+            if (DEBUG) {
+                Log.d(TAG, "onLayoutSurface (left=" + left + ", top=" + top + ", right="
+                        + right + ", bottom=" + bottom + ",)");
+            }
+            mSurfaceViewLeft = left;
+            mSurfaceViewTop = top;
+            mSurfaceViewRight = right;
+            mSurfaceViewBottom = bottom;
+            mUseRequestedSurfaceLayout = true;
+            requestLayout();
+        }
+
+        @Override
         public void onSessionEvent(Session session, String eventType, Bundle eventArgs) {
             if (this != mSessionCallback) {
                 return;
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 5f27b16..c678ac7 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -966,6 +966,22 @@
     return certificateObj;
 }
 
+static void android_media_MediaDrm_unprovisionDeviceNative(
+    JNIEnv *env, jobject thiz) {
+    sp<IDrm> drm = GetDrm(env, thiz);
+
+    if (drm == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                          "MediaDrm obj is null");
+        return;
+    }
+
+    status_t err = drm->unprovisionDevice();
+
+    throwExceptionAsNecessary(env, err, "Failed to handle provision response");
+    return;
+}
+
 static jobject android_media_MediaDrm_getSecureStops(
     JNIEnv *env, jobject thiz) {
     sp<IDrm> drm = GetDrm(env, thiz);
@@ -1362,6 +1378,9 @@
     { "provideProvisionResponseNative", "([B)Landroid/media/MediaDrm$Certificate;",
       (void *)android_media_MediaDrm_provideProvisionResponseNative },
 
+    { "unprovisionDevice", "()V",
+      (void *)android_media_MediaDrm_unprovisionDeviceNative },
+
     { "getSecureStops", "()Ljava/util/List;",
       (void *)android_media_MediaDrm_getSecureStops },
 
@@ -1408,4 +1427,3 @@
     return AndroidRuntime::registerNativeMethods(env,
                 "android/media/MediaDrm", gMethods, NELEM(gMethods));
 }
-
diff --git a/native/android/sensor.cpp b/native/android/sensor.cpp
index b09bc2e..73b52aa 100644
--- a/native/android/sensor.cpp
+++ b/native/android/sensor.cpp
@@ -59,6 +59,19 @@
     return static_cast<SensorManager*>(manager)->getDefaultSensor(type);
 }
 
+ASensor const* ASensorManager_getDefaultSensorEx(ASensorManager* manager,
+        int type, bool wakeUp) {
+    Sensor const* const* sensorList;
+    size_t size = static_cast<SensorManager*>(manager)->getSensorList(&sensorList);
+    for (size_t i = 0; i < size; ++i) {
+        if (ASensor_getType(sensorList[i]) == type &&
+            ASensor_isWakeUpSensor(sensorList[i]) == wakeUp) {
+            return reinterpret_cast<ASensor const *>(sensorList[i]);
+       }
+    }
+    return NULL;
+}
+
 ASensorEventQueue* ASensorManager_createEventQueue(ASensorManager* manager,
         ALooper* looper, int ident, ALooper_callbackFunc callback, void* data)
 {
@@ -176,3 +189,8 @@
 {
     return static_cast<Sensor const*>(sensor)->getReportingMode();
 }
+
+bool ASensor_isWakeUpSensor(ASensor const* sensor)
+{
+    return static_cast<Sensor const*>(sensor)->isWakeUpSensor();
+}
\ No newline at end of file
diff --git a/packages/CaptivePortalLogin/AndroidManifest.xml b/packages/CaptivePortalLogin/AndroidManifest.xml
index 5f78afe..c5fb167 100644
--- a/packages/CaptivePortalLogin/AndroidManifest.xml
+++ b/packages/CaptivePortalLogin/AndroidManifest.xml
@@ -25,7 +25,7 @@
         <activity
             android:name="com.android.captiveportallogin.CaptivePortalLoginActivity"
             android:label="@string/action_bar_label"
-            android:theme="@android:style/Theme.Holo" >
+            android:theme="@style/AppTheme" >
             <intent-filter>
                 <action android:name="android.intent.action.ACTION_SEND"/>
                 <category android:name="android.intent.category.DEFAULT"/>
diff --git a/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml b/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml
index d8f2928..a11bed0 100644
--- a/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml
+++ b/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml
@@ -5,9 +5,16 @@
     android:layout_height="match_parent"
     tools:context="com.android.captiveportallogin.CaptivePortalLoginActivity"
     tools:ignore="MergeRootFrame">
-    <RelativeLayout
+    <LinearLayout
     android:layout_width="match_parent"
-    android:layout_height="match_parent" >
+    android:layout_height="match_parent"
+    android:orientation="vertical" >
+
+    <ProgressBar
+        android:id="@+id/progress_bar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        style="?android:attr/progressBarStyleHorizontal" />
 
     <WebView
         android:id="@+id/webview"
@@ -16,5 +23,5 @@
         android:layout_alignParentBottom="false"
         android:layout_alignParentRight="false" />
 
-</RelativeLayout>
+</LinearLayout>
 </FrameLayout>
diff --git a/packages/CaptivePortalLogin/res/values-af/strings.xml b/packages/CaptivePortalLogin/res/values-af/strings.xml
new file mode 100644
index 0000000..a543266
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-af/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">"CaptivePortal-aanmelding"</string>
+    <string name="action_use_network" msgid="6076184727448466030">"Gebruik hierdie netwerk nes dit is"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Moenie hierdie netwerk gebruik nie"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Meld aan by netwerk"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-am/strings.xml b/packages/CaptivePortalLogin/res/values-am/strings.xml
new file mode 100644
index 0000000..bfad2d1
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-am/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">"ይህን አውታረ መረብ እንዳለ ተጠቀምበት"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"ይህን አውታረ መረብ አትጠቀምበት"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"ወደ አውታረ መረብ በመለያ ይግቡ"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ar/strings.xml b/packages/CaptivePortalLogin/res/values-ar/strings.xml
new file mode 100644
index 0000000..cb2e484
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-ar/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">"استخدام هذه الشبكة كما هي"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"عدم استخدام هذه الشبكة"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"تسجيل الدخول إلى الشبكة"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-bg/strings.xml b/packages/CaptivePortalLogin/res/values-bg/strings.xml
new file mode 100644
index 0000000..c56af54
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-bg/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">"Директно използване на тази мрежа"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Без използване на тази мрежа"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Вход в мрежата"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-bn-rBD/strings.xml b/packages/CaptivePortalLogin/res/values-bn-rBD/strings.xml
new file mode 100644
index 0000000..51a2b78
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-bn-rBD/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">"যেভাবে আছে সেভাবেই এই নেটওয়ার্ক ব্যবহার করুন"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"এই নেটওয়ার্ক ব্যবহার করবেন না"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"নেটওয়ার্কে সাইন ইন করুন"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ca/strings.xml b/packages/CaptivePortalLogin/res/values-ca/strings.xml
new file mode 100644
index 0000000..a26a11d
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-ca/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">"Fes servir aquesta xarxa tal com està."</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"No facis servir aquesta xarxa."</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"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
new file mode 100644
index 0000000..a1639b8
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-cs/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">"Použít tuto síť tak, jak je"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Tuto síť nepoužívat"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Přihlásit se k síti"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-da/strings.xml b/packages/CaptivePortalLogin/res/values-da/strings.xml
new file mode 100644
index 0000000..a48eeac
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-da/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">"Login til captive portal"</string>
+    <string name="action_use_network" msgid="6076184727448466030">"Brug dette netværk, som det er"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Brug ikke dette netværk"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Login til netværk"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-de/strings.xml b/packages/CaptivePortalLogin/res/values-de/strings.xml
new file mode 100644
index 0000000..86c8d1f
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-de/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">"Dieses Netzwerk im Istzustand verwenden"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Dieses Netzwerk nicht verwenden"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Im Netzwerk anmelden"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-el/strings.xml b/packages/CaptivePortalLogin/res/values-el/strings.xml
new file mode 100644
index 0000000..f9a5b0f
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-el/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">"Χρήση αυτού του δικτύου ως έχει"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Να μη χρησιμοποιείται αυτό το δίκτυο"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Σύνδεση στο δίκτυο"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-es-rUS/strings.xml b/packages/CaptivePortalLogin/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..2c2e882
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-es-rUS/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">"Usar esta red como está"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"No usar esta red"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Acceder a la red"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-es/strings.xml b/packages/CaptivePortalLogin/res/values-es/strings.xml
new file mode 100644
index 0000000..6ea2ab7
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-es/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">"Utilizar esta red tal cual"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"No utilizar esta red"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Iniciar sesión en red"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-et-rEE/strings.xml b/packages/CaptivePortalLogin/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..95c7eba
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-et-rEE/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">"Kasuta seda võrku olemasoleval kujul"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ära kasuta seda võrku"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Võrku sisselogimine"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-eu-rES/strings.xml b/packages/CaptivePortalLogin/res/values-eu-rES/strings.xml
new file mode 100644
index 0000000..98ccb53
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-eu-rES/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">"Erabili sare hau bere horretan"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ez erabili sare hau"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Hasi saioa sarean"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-fa/strings.xml b/packages/CaptivePortalLogin/res/values-fa/strings.xml
new file mode 100644
index 0000000..36e53c1
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-fa/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">"از این شبکه همانطور که هست استفاده شود"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"از این شبکه استفاده نشود"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"وارد شدن به سیستم شبکه"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-fi/strings.xml b/packages/CaptivePortalLogin/res/values-fi/strings.xml
new file mode 100644
index 0000000..fb44d99
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-fi/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">"Käytä tätä verkkoa sellaisenaan"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Älä käytä tätä verkkoa"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Kirjaudu verkkoon"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-fr-rCA/strings.xml b/packages/CaptivePortalLogin/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..7ef7449
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-fr-rCA/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">"Utiliser ce réseau tel quel"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne pas utiliser ce réseau"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Connectez-vous au réseau"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-fr/strings.xml b/packages/CaptivePortalLogin/res/values-fr/strings.xml
new file mode 100644
index 0000000..b8cb9d2
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-fr/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">"Utiliser ce réseau tel quel"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne pas utiliser ce réseau"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"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
new file mode 100644
index 0000000..0c967d5
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-gl-rES/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">"Utilizar esta rede tal como está"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Non utilizar esta rede"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"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
new file mode 100644
index 0000000..2bf4a07
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-hi/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">"इस नेटवर्क का उपयोग जैसा है वैसा ही करें"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"इस नेटवर्क का उपयोग न करें"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"नेटवर्क में प्रवेश करें"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-hr/strings.xml b/packages/CaptivePortalLogin/res/values-hr/strings.xml
new file mode 100644
index 0000000..1a51195
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-hr/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">"Upotrebljavaj ovu mrežu u zatečenom stanju"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne upotrebljavaj ovu mrežu"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Prijavi se na mrežu"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-hu/strings.xml b/packages/CaptivePortalLogin/res/values-hu/strings.xml
new file mode 100644
index 0000000..ea3a66b
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-hu/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">"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>
+    <string name="action_bar_label" msgid="2573986763322074279">"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
new file mode 100644
index 0000000..381b53d
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-hy-rAM/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">"Օգտագործել այս ցանցն ինչպես կա"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Չօգտագործել այս ցանցը"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Մուտք գործել ցանց"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-in/strings.xml b/packages/CaptivePortalLogin/res/values-in/strings.xml
new file mode 100644
index 0000000..20a15ca
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-in/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">"Gunakan jaringan ini sebagaimana adanya"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Jangan gunakan jaringan ini"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Masuk ke jaringan"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-is-rIS/strings.xml b/packages/CaptivePortalLogin/res/values-is-rIS/strings.xml
new file mode 100644
index 0000000..127bb83
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-is-rIS/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">"Nota þetta net óbreytt"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ekki nota þetta net"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Skrá þig inn á netið"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-it/strings.xml b/packages/CaptivePortalLogin/res/values-it/strings.xml
new file mode 100644
index 0000000..0c62b98
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-it/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">"Utilizza questa rete così com\'è"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Non utilizzare questa rete"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Accedi alla rete"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-iw/strings.xml b/packages/CaptivePortalLogin/res/values-iw/strings.xml
new file mode 100644
index 0000000..9abfb61
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-iw/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">"השתמש ברשת זו כפי שהיא"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"אל תשתמש ברשת זו"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"היכנס לרשת"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ja/strings.xml b/packages/CaptivePortalLogin/res/values-ja/strings.xml
new file mode 100644
index 0000000..1328011
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-ja/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">"このネットワークをそのまま使用する"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"このネットワークを使用しない"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"ネットワークにログインする"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ka-rGE/strings.xml b/packages/CaptivePortalLogin/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..a429669
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-ka-rGE/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">"ამ ქსელის გამოყენება, როგორც არის"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"ეს ქსელი არ გამოიყენო"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"ქსელთან დაკავშირება"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-kk-rKZ/strings.xml b/packages/CaptivePortalLogin/res/values-kk-rKZ/strings.xml
new file mode 100644
index 0000000..fcb6584
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-kk-rKZ/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">"Осы желіні бар күйінде пайдалану"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Осы желіні пайдаланбау"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Желіге кіру"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-km-rKH/strings.xml b/packages/CaptivePortalLogin/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..8cdedd4
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-km-rKH/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">"ប្រើ​បណ្ដាញ​នេះ​ជា"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"កុំ​ប្រើ​បណ្ដាញ​នេះ"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"ចូល​បណ្ដាញ"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-kn-rIN/strings.xml b/packages/CaptivePortalLogin/res/values-kn-rIN/strings.xml
new file mode 100644
index 0000000..070ba52
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-kn-rIN/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">"ಈ ನೆಟ್‌ವರ್ಕ್ ಅನ್ನು ಹೀಗೆ ಬಳಸಿ"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"ಈ ನೆಟ್‌ವರ್ಕ್ ಬಳಸಬೇಡಿ"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ko/strings.xml b/packages/CaptivePortalLogin/res/values-ko/strings.xml
new file mode 100644
index 0000000..c72511b
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-ko/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">"현재 상태로 이 네트워크 사용"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"이 네트워크 사용 안함"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"네트워크에 로그인"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ky-rKG/strings.xml b/packages/CaptivePortalLogin/res/values-ky-rKG/strings.xml
new file mode 100644
index 0000000..eb16c6c
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-ky-rKG/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">"Бул тармак кандай болсо, ошондой колдонулсун"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Бул тармак колдонулбасын"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Тармакка кирүү"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-lo-rLA/strings.xml b/packages/CaptivePortalLogin/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..f2b637c
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-lo-rLA/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">"​ໃຊ້​ເຄືອ​ຂ່າຍ​ນີ້​ຕາມ​ທີ່​ມັນ​ເປັນ"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"ບໍ່​ໃຊ້​ເຄືອ​ຂ່າຍ​ນີ້"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"​ເຂົ້າ​ສູ່​ລະ​ບົບ​ຫາ​ເຄືອ​ຂ່າຍ"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-lt/strings.xml b/packages/CaptivePortalLogin/res/values-lt/strings.xml
new file mode 100644
index 0000000..00ca28d
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-lt/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">"Naudoti šį tinklą tokį, koks yra"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Nenaudoti šio tinklo"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Prisijungti prie tinklo"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-lv/strings.xml b/packages/CaptivePortalLogin/res/values-lv/strings.xml
new file mode 100644
index 0000000..0912497
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-lv/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">"Izmantot tīklu ar pašreizējiem iestatījumiem"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Neizmantot šo tīklu"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"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
new file mode 100644
index 0000000..5fd27a2
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-mk-rMK/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">"Користи ја мрежата во оваа состојба"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не ја користи мрежата"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Пријави се на мрежа"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ml-rIN/strings.xml b/packages/CaptivePortalLogin/res/values-ml-rIN/strings.xml
new file mode 100644
index 0000000..ff7c6cc
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-ml-rIN/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">"ഈ നെറ്റ്‌വർക്ക് മാറ്റമൊന്നും വരുത്താതെ ഉപയോഗിക്കുക"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"ഈ നെറ്റ്‌വർക്ക് ഉപയോഗിക്കരുത്"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"നെറ്റ്‌വർക്കിൽ സൈൻ ഇൻ ചെയ്യുക"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-mn-rMN/strings.xml b/packages/CaptivePortalLogin/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..5ce9e7e
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-mn-rMN/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">"Энэ сүлжээг ашиглана уу"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Энэ сүлжээг бүү ашиглана уу"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Сүлжээнд нэвтрэх"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-mr-rIN/strings.xml b/packages/CaptivePortalLogin/res/values-mr-rIN/strings.xml
new file mode 100644
index 0000000..082e7ad
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-mr-rIN/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">"हे नेटवर्क जसेच्या तसे वापरा"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"हे नेटवर्क वापरू नका"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"नेटवर्कवर साइन इन करा"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ms-rMY/strings.xml b/packages/CaptivePortalLogin/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..f3d2918
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-ms-rMY/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">"Gunakan rangkaian ini"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Jangan gunakan rangkaian ini"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Log masuk ke rangkaian"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-nb/strings.xml b/packages/CaptivePortalLogin/res/values-nb/strings.xml
new file mode 100644
index 0000000..8bdf95b
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-nb/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">"Bruk dette nettverket som det er"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ikke bruk dette nettverket"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Logg på nettverk"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ne-rNP/strings.xml b/packages/CaptivePortalLogin/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..7fcaf07
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-ne-rNP/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">"यो सञ्जाल जस्तो छ प्रयोग गर्नुहोस्"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"यो सञ्जाल प्रयोग नगर्नुहोस्"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"सञ्जालमा साइन इन गर्नुहोस्"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-nl/strings.xml b/packages/CaptivePortalLogin/res/values-nl/strings.xml
new file mode 100644
index 0000000..063c91e
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-nl/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">"Dit netwerk in de huidige staat gebruiken"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Dit netwerk niet gebruiken"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Inloggen bij netwerk"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pl/strings.xml b/packages/CaptivePortalLogin/res/values-pl/strings.xml
new file mode 100644
index 0000000..e1f6eb4
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-pl/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">"Używaj tej sieci tak jak jest"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Nie używaj tej sieci"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Zaloguj się w sieci"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pt-rPT/strings.xml b/packages/CaptivePortalLogin/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..1b07222
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-pt-rPT/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">"Utilizar esta rede como está"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Não utilizar esta rede"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Início de sessão na rede"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pt/strings.xml b/packages/CaptivePortalLogin/res/values-pt/strings.xml
new file mode 100644
index 0000000..4208912
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-pt/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">"Usar esta rede como está"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Não usar esta rede"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Fazer login na rede"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ro/strings.xml b/packages/CaptivePortalLogin/res/values-ro/strings.xml
new file mode 100644
index 0000000..272967f
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-ro/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">"Utilizați această rețea în starea actuală"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Nu utilizați această rețea"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Conectați-vă la rețea"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ru/strings.xml b/packages/CaptivePortalLogin/res/values-ru/strings.xml
new file mode 100644
index 0000000..6e7a85f
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-ru/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">"Использовать эту сеть"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не использовать эту сеть"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Подключиться к сети"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-si-rLK/strings.xml b/packages/CaptivePortalLogin/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..7fb17b9
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-si-rLK/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">"මෙම ජාලය ලෙසම භාවිතා කරන්න"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"මෙම ජාලය භාවිතා කරන්න එපා"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"ජාලයට පුරනය වන්න"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sk/strings.xml b/packages/CaptivePortalLogin/res/values-sk/strings.xml
new file mode 100644
index 0000000..514b4c8
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-sk/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">"Použiť túto sieť tak, ako je"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Túto sieť nepoužívať"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Prihlásiť sa do siete"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sl/strings.xml b/packages/CaptivePortalLogin/res/values-sl/strings.xml
new file mode 100644
index 0000000..6748126
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-sl/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">"Uporabljajte to omrežje, »kakršno je«"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne uporabljajte tega omrežja"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"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
new file mode 100644
index 0000000..1b86247
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-sr/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">"Користи ову мрежу такву каква је"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не користи ову мрежу"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Пријави ме на мрежу"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sv/strings.xml b/packages/CaptivePortalLogin/res/values-sv/strings.xml
new file mode 100644
index 0000000..5436c51
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-sv/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">"Använd det här nätverket som det är"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Använd inte det här nätverket"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Logga in på nätverket"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sw/strings.xml b/packages/CaptivePortalLogin/res/values-sw/strings.xml
new file mode 100644
index 0000000..460e66f
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-sw/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">"Tumia mtandao huu jinsi ulivyo"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Usitumie mtandao huu"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Ingia katika mtandao"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ta-rIN/strings.xml b/packages/CaptivePortalLogin/res/values-ta-rIN/strings.xml
new file mode 100644
index 0000000..d8626a4
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-ta-rIN/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">"இந்த நெட்வொர்க்கைப் பயன்படுத்து"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"இந்த நெட்வொர்க்கைப் பயன்படுத்த வேண்டாம்"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"நெட்வொர்க்கில் உள்நுழையவும்"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-te-rIN/strings.xml b/packages/CaptivePortalLogin/res/values-te-rIN/strings.xml
new file mode 100644
index 0000000..7cbd81b
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-te-rIN/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">"ఈ నెట్‌వర్క్‌ని యథావిధిగా ఉపయోగించు"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"ఈ నెట్‌వర్క్‌ని ఉపయోగించవద్దు"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"నెట్‌వర్క్‌కి సైన్-ఇన్ చేయండి"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-th/strings.xml b/packages/CaptivePortalLogin/res/values-th/strings.xml
new file mode 100644
index 0000000..be50b9a
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-th/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">"ใช้เครือข่ายนี้ตามที่เป็นอยู่"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"ไม่ใช้เครือข่ายนี้"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"ลงชื่อเข้าใช้เครือข่าย"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-tl/strings.xml b/packages/CaptivePortalLogin/res/values-tl/strings.xml
new file mode 100644
index 0000000..76d0ff8
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-tl/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">"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>
+    <string name="action_bar_label" msgid="2573986763322074279">"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
new file mode 100644
index 0000000..752e4af
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-tr/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">"Bu ağı olduğu gibi kullan"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Bu ağı kullanma"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Ağda oturum aç"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-uk/strings.xml b/packages/CaptivePortalLogin/res/values-uk/strings.xml
new file mode 100644
index 0000000..028a724
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-uk/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">"Використовувати цю мережу як є"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не використовувати цю мережу"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Увійти в мережу"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ur-rPK/strings.xml b/packages/CaptivePortalLogin/res/values-ur-rPK/strings.xml
new file mode 100644
index 0000000..af91d95
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-ur-rPK/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">"جوں کا توں اس نیٹ ورک کا استعمال کریں"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"اس نیٹ ورک کا استعمال نہ کریں"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"نیٹ ورک میں سائن ان کریں"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-uz-rUZ/strings.xml b/packages/CaptivePortalLogin/res/values-uz-rUZ/strings.xml
new file mode 100644
index 0000000..8fca0f0
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-uz-rUZ/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">"Ushbu tarmoqdan o‘z holicha foydalanilsin"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ushbu tarmoqdan foydalanilmasin"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Tarmoqqa kirish"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-vi/strings.xml b/packages/CaptivePortalLogin/res/values-vi/strings.xml
new file mode 100644
index 0000000..64d2ddf
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-vi/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">"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>
+    <string name="action_bar_label" msgid="2573986763322074279">"Đă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
new file mode 100644
index 0000000..628d597
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-zh-rCN/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">"直接使用此网络"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"不要使用此网络"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"登录到网络"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml b/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..4ca9e0b
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-zh-rHK/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">"依照現況使用這個網絡"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"不要使用這個網絡"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"登入網絡"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml b/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..cf498e4
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-zh-rTW/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">"依現況使用這個網路"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"不使用這個網路"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"登入網路"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-zu/strings.xml b/packages/CaptivePortalLogin/res/values-zu/strings.xml
new file mode 100644
index 0000000..180367c
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-zu/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">"I-CaptivePortalLogin"</string>
+    <string name="action_use_network" msgid="6076184727448466030">"Sebenzisa le nethiwekhi njengoba injalo"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ungasebenzisi le nethiwekhi"</string>
+    <string name="action_bar_label" msgid="2573986763322074279">"Ngena ngemvume kunethiwekhi"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values/styles.xml b/packages/CaptivePortalLogin/res/values/styles.xml
index 6ce89c7..7ccd3d3 100644
--- a/packages/CaptivePortalLogin/res/values/styles.xml
+++ b/packages/CaptivePortalLogin/res/values/styles.xml
@@ -4,7 +4,7 @@
         Base application theme, dependent on API level. This theme is replaced
         by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
     -->
-    <style name="AppBaseTheme" parent="android:Theme.Light">
+    <style name="AppBaseTheme" parent="@android:style/Theme.Material.Settings">
         <!--
             Theme customizations available in newer API levels can go in
             res/values-vXX/styles.xml, while customizations related to
@@ -15,6 +15,8 @@
     <!-- Application theme. -->
     <style name="AppTheme" parent="AppBaseTheme">
         <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+        <!-- Setting's theme's accent color makes ProgressBar useless, reset back. -->
+        <item name="android:colorAccent">@*android:color/material_light_blue_A200</item>
     </style>
 
 </resources>
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index 09525b2..ae52a1e 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -26,11 +26,13 @@
 import android.provider.Settings.Global;
 import android.view.Menu;
 import android.view.MenuItem;
+import android.view.View;
 import android.view.Window;
 import android.webkit.WebChromeClient;
 import android.webkit.WebSettings;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
+import android.widget.ProgressBar;
 
 import java.io.IOException;
 import java.net.HttpURLConnection;
@@ -66,7 +68,6 @@
             done(true);
         }
 
-        requestWindowFeature(Window.FEATURE_PROGRESS);
         setContentView(R.layout.activity_captive_portal_login);
 
         getActionBar().setDisplayShowHomeEnabled(false);
@@ -164,7 +165,9 @@
     private class MyWebChromeClient extends WebChromeClient {
         @Override
         public void onProgressChanged(WebView view, int newProgress) {
-            setProgress(newProgress*100);
+            ProgressBar myProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
+            myProgressBar.setProgress(newProgress);
+            myProgressBar.setVisibility(newProgress == 100 ? View.GONE : View.VISIBLE);
         }
     }
 }
diff --git a/packages/DocumentsUI/res/layout/fragment_directory.xml b/packages/DocumentsUI/res/layout/fragment_directory.xml
index ffbd3f0..c8c707e 100644
--- a/packages/DocumentsUI/res/layout/fragment_directory.xml
+++ b/packages/DocumentsUI/res/layout/fragment_directory.xml
@@ -26,7 +26,7 @@
         android:gravity="center"
         android:text="@string/empty"
         android:visibility="gone"
-        style="@style/TextAppearance.Medium" />
+        style="@android:style/TextAppearance.Material.Subhead" />
 
     <ListView
         android:id="@+id/list"
diff --git a/packages/DocumentsUI/res/values-sw720dp/styles.xml b/packages/DocumentsUI/res/values-sw720dp/styles.xml
new file mode 100644
index 0000000..9968bb8
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sw720dp/styles.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <style name="DialogWhenReallyLarge" parent="@*android:style/Theme.DeviceDefault.Light.Dialog.FixedSize" />
+
+</resources>
diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml
index 4bd6991..573081c 100644
--- a/packages/DocumentsUI/res/values/styles.xml
+++ b/packages/DocumentsUI/res/values/styles.xml
@@ -16,7 +16,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <style name="DocumentsTheme" parent="@android:style/Theme.DeviceDefault.Light.DialogWhenLarge">
+    <style name="DialogWhenReallyLarge" parent="@android:style/Theme.DeviceDefault.Light" />
+
+    <style name="DocumentsTheme" parent="@style/DialogWhenReallyLarge">
         <item name="android:actionBarWidgetTheme">@null</item>
         <item name="android:actionBarTheme">@*android:style/ThemeOverlay.Material.Dark.ActionBar</item>
         <item name="android:actionBarPopupTheme">@*android:style/ThemeOverlay.Material.Light</item>
@@ -38,16 +40,4 @@
         <item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
     </style>
 
-    <style name="TextAppearance" />
-
-    <style name="TextAppearance.Medium">
-        <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
-        <item name="android:textColor">?android:attr/textColorSecondary</item>
-    </style>
-
-    <style name="TextAppearance.Small">
-        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
-        <item name="android:textColor">?android:attr/textColorTertiary</item>
-    </style>
-
 </resources>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SortingCursorWrapper.java b/packages/DocumentsUI/src/com/android/documentsui/SortingCursorWrapper.java
index a23dd15..6c8ca20 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/SortingCursorWrapper.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/SortingCursorWrapper.java
@@ -27,6 +27,8 @@
 import android.os.Bundle;
 import android.provider.DocumentsContract.Document;
 
+import com.android.documentsui.model.DocumentInfo;
+
 /**
  * Cursor wrapper that presents a sorted view of the underlying cursor. Handles
  * common {@link Document} sorting modes, such as ordering directories first.
@@ -68,7 +70,7 @@
                     final String displayName = getCursorString(
                             cursor, Document.COLUMN_DISPLAY_NAME);
                     if (Document.MIME_TYPE_DIR.equals(mimeType)) {
-                        mValueString[i] = '\001' + displayName;
+                        mValueString[i] = DocumentInfo.DIR_PREFIX + displayName;
                     } else {
                         mValueString[i] = displayName;
                     }
@@ -180,14 +182,7 @@
 
                 final String lhs = pivotValue;
                 final String rhs = value[mid];
-                final int compare;
-                if (lhs == null) {
-                    compare = -1;
-                } else if (rhs == null) {
-                    compare = 1;
-                } else {
-                    compare = lhs.compareToIgnoreCase(rhs);
-                }
+                final int compare = DocumentInfo.compareToIgnoreCaseNullable(lhs, rhs);
 
                 if (compare < 0) {
                     right = mid;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
index 91d9124..1c5ca86 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
@@ -25,6 +25,7 @@
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsProvider;
+import android.text.TextUtils;
 
 import com.android.documentsui.DocumentsApplication;
 import com.android.documentsui.RootCursorWrapper;
@@ -36,6 +37,7 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.net.ProtocolException;
+import java.text.Collator;
 
 /**
  * Representation of a {@link Document}.
@@ -44,6 +46,13 @@
     private static final int VERSION_INIT = 1;
     private static final int VERSION_SPLIT_URI = 2;
 
+    private static final Collator sCollator;
+
+    static {
+        sCollator = Collator.getInstance();
+        sCollator.setStrength(Collator.SECONDARY);
+    }
+
     public String authority;
     public String documentId;
     public String mimeType;
@@ -268,9 +277,30 @@
         throw fnfe;
     }
 
+    /**
+     * String prefix used to indicate the document is a directory.
+     */
+    public static final char DIR_PREFIX = '\001';
+
+    /**
+     * Compare two strings against each other using system default collator in a
+     * case-insensitive mode. Clusters strings prefixed with {@link #DIR_PREFIX}
+     * before other items.
+     */
     public static int compareToIgnoreCaseNullable(String lhs, String rhs) {
-        if (lhs == null) return -1;
-        if (rhs == null) return 1;
-        return lhs.compareToIgnoreCase(rhs);
+        final boolean leftEmpty = TextUtils.isEmpty(lhs);
+        final boolean rightEmpty = TextUtils.isEmpty(rhs);
+
+        if (leftEmpty && rightEmpty) return 0;
+        if (leftEmpty) return -1;
+        if (rightEmpty) return 1;
+
+        final boolean leftDir = (lhs.charAt(0) == DIR_PREFIX);
+        final boolean rightDir = (rhs.charAt(0) == DIR_PREFIX);
+
+        if (leftDir && !rightDir) return -1;
+        if (rightDir && !leftDir) return 1;
+
+        return sCollator.compare(lhs, rhs);
     }
 }
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 9473eb9..c323a33 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -18,6 +18,7 @@
 
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
 import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
 import android.database.MatrixCursor;
@@ -28,7 +29,9 @@
 import android.os.Environment;
 import android.os.FileObserver;
 import android.os.FileUtils;
+import android.os.Handler;
 import android.os.ParcelFileDescriptor;
+import android.os.ParcelFileDescriptor.OnCloseListener;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageVolume;
 import android.provider.DocumentsContract;
@@ -80,6 +83,7 @@
     private static final String ROOT_ID_PRIMARY_EMULATED = "primary";
 
     private StorageManager mStorageManager;
+    private Handler mHandler;
 
     private final Object mRootsLock = new Object();
 
@@ -96,6 +100,7 @@
     @Override
     public boolean onCreate() {
         mStorageManager = (StorageManager) getContext().getSystemService(Context.STORAGE_SERVICE);
+        mHandler = new Handler();
 
         mRoots = Lists.newArrayList();
         mIdToRoot = Maps.newHashMap();
@@ -422,7 +427,25 @@
             String documentId, String mode, CancellationSignal signal)
             throws FileNotFoundException {
         final File file = getFileForDocId(documentId);
-        return ParcelFileDescriptor.open(file, ParcelFileDescriptor.parseMode(mode));
+        final int pfdMode = ParcelFileDescriptor.parseMode(mode);
+        if (pfdMode == ParcelFileDescriptor.MODE_READ_ONLY) {
+            return ParcelFileDescriptor.open(file, pfdMode);
+        } else {
+            try {
+                // When finished writing, kick off media scanner
+                return ParcelFileDescriptor.open(file, pfdMode, mHandler, new OnCloseListener() {
+                    @Override
+                    public void onClose(IOException e) {
+                        final Intent intent = new Intent(
+                                Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
+                        intent.setData(Uri.fromFile(file));
+                        getContext().sendBroadcast(intent);
+                    }
+                });
+            } catch (IOException e) {
+                throw new FileNotFoundException("Failed to open for writing: " + e);
+            }
+        }
     }
 
     @Override
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_activated.png b/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_activated.png
deleted file mode 100644
index c0e2098..0000000
--- a/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_activated.png
+++ /dev/null
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_normal.png
deleted file mode 100644
index a852e2c..0000000
--- a/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_activated.png b/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_activated.png
deleted file mode 100644
index f88f7e1..0000000
--- a/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_activated.png
+++ /dev/null
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_normal.png
deleted file mode 100644
index 7426994..0000000
--- a/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_activated.png b/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_activated.png
deleted file mode 100644
index 500b157..0000000
--- a/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_activated.png
+++ /dev/null
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_normal.png
deleted file mode 100644
index d0e4cf3..0000000
--- a/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/Keyguard/res/drawable/ic_action_assist_generic.xml b/packages/Keyguard/res/drawable/ic_action_assist_generic.xml
deleted file mode 100644
index 60f5d5d..0000000
--- a/packages/Keyguard/res/drawable/ic_action_assist_generic.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <item
-        android:state_enabled="true"
-        android:state_active="false"
-        android:state_focused="false"
-        android:drawable="@drawable/ic_action_assist_generic_normal" />
-
-    <item
-        android:state_enabled="true"
-        android:state_active="true"
-        android:state_focused="false"
-        android:drawable="@drawable/ic_action_assist_generic_activated" />
-
-    <item
-        android:state_enabled="true"
-        android:state_active="false"
-        android:state_focused="true"
-        android:drawable="@drawable/ic_action_assist_generic_activated" />
-
-</selector>
diff --git a/packages/Keyguard/res/layout/keyguard_glow_pad_view.xml b/packages/Keyguard/res/layout/keyguard_glow_pad_view.xml
index 3a466dd..2432336 100644
--- a/packages/Keyguard/res/layout/keyguard_glow_pad_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_glow_pad_view.xml
@@ -28,10 +28,6 @@
     android:orientation="horizontal"
     android:gravity="@integer/kg_selector_gravity"
     android:contentDescription="@string/keyguard_accessibility_slide_area"
-
-    prvandroid:targetDrawables="@array/lockscreen_targets_unlock_only"
-    prvandroid:targetDescriptions="@array/lockscreen_target_descriptions_unlock_only"
-    prvandroid:directionDescriptions="@array/lockscreen_direction_descriptions"
     prvandroid:handleDrawable="@drawable/ic_lockscreen_handle"
     prvandroid:outerRingDrawable="@drawable/ic_lockscreen_outerring"
     prvandroid:outerRadius="@dimen/glowpadview_target_placement_radius"
diff --git a/packages/Keyguard/res/values-land/arrays.xml b/packages/Keyguard/res/values-land/arrays.xml
deleted file mode 100644
index 240b9e4..0000000
--- a/packages/Keyguard/res/values-land/arrays.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/colors.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:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <!-- Resources for GlowPadView in LockScreen -->
-    <array name="lockscreen_targets_when_silent">
-        <item>@null</item>"
-        <item>@drawable/ic_action_assist_generic</item>
-        <item>@drawable/ic_lockscreen_soundon</item>
-        <item>@drawable/ic_lockscreen_unlock</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_when_silent">
-        <item>@null</item>
-        <item>@string/description_target_search</item>
-        <item>@string/description_target_soundon</item>
-        <item>@string/description_target_unlock</item>
-    </array>
-
-    <array name="lockscreen_direction_descriptions">
-        <item>@null</item>
-        <item>@string/description_direction_up</item>
-        <item>@string/description_direction_left</item>
-        <item>@string/description_direction_down</item>
-    </array>
-
-    <array name="lockscreen_targets_when_soundon">
-        <item>@null</item>
-        <item>@drawable/ic_action_assist_generic</item>
-        <item>@drawable/ic_lockscreen_silent</item>
-        <item>@drawable/ic_lockscreen_unlock</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_when_soundon">
-        <item>@null</item>
-        <item>@string/description_target_search</item>
-        <item>@string/description_target_silent</item>
-        <item>@string/description_target_unlock</item>
-    </array>
-
-    <array name="lockscreen_targets_with_camera">
-        <item>@null</item>
-        <item>@drawable/ic_action_assist_generic</item>
-        <item>@drawable/ic_lockscreen_camera</item>
-        <item>@drawable/ic_lockscreen_unlock</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_with_camera">
-        <item>@null</item>
-        <item>@string/description_target_search</item>
-        <item>@string/description_target_camera</item>
-        <item>@string/description_target_unlock</item>
-    </array>
-
-</resources>
diff --git a/packages/Keyguard/res/values-sw600dp-land/arrays.xml b/packages/Keyguard/res/values-sw600dp-land/arrays.xml
deleted file mode 100644
index 5550216..0000000
--- a/packages/Keyguard/res/values-sw600dp-land/arrays.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/colors.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:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <!-- Resources for GlowPadView in LockScreen -->
-    <array name="lockscreen_targets_when_silent">
-        <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@null</item>
-        <item>@drawable/ic_lockscreen_soundon</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_when_silent">
-        <item>@string/description_target_unlock</item>
-        <item>@null</item>
-        <item>@string/description_target_soundon</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_direction_descriptions">
-        <item>@string/description_direction_right</item>
-        <item>@null</item>
-        <item>@string/description_direction_left</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_targets_when_soundon">
-        <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@null</item>
-        <item>@drawable/ic_lockscreen_silent</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_when_soundon">
-        <item>@string/description_target_unlock</item>
-        <item>@null</item>
-        <item>@string/description_target_silent</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_targets_with_camera">
-        <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@drawable/ic_action_assist_generic</item>
-        <item>@drawable/ic_lockscreen_camera</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_with_camera">
-        <item>@string/description_target_unlock</item>
-        <item>@string/description_target_search</item>
-        <item>@string/description_target_camera</item>
-        <item>@null</item>
-    </array>
-
-</resources>
diff --git a/packages/Keyguard/res/values/arrays.xml b/packages/Keyguard/res/values/arrays.xml
index 291f776..a8b3c1b 100644
--- a/packages/Keyguard/res/values/arrays.xml
+++ b/packages/Keyguard/res/values/arrays.xml
@@ -19,64 +19,6 @@
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
-    <!-- Resources for GlowPadView in LockScreen -->
-    <array name="lockscreen_targets_when_silent">
-        <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@drawable/ic_action_assist_generic</item>
-        <item>@drawable/ic_lockscreen_soundon</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_when_silent">
-        <item>@string/description_target_unlock</item>
-        <item>@string/description_target_search</item>
-        <item>@string/description_target_soundon</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_direction_descriptions">
-        <item>@string/description_direction_right</item>
-        <item>@string/description_direction_up</item>
-        <item>@string/description_direction_left</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_targets_when_soundon">
-        <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@drawable/ic_action_assist_generic</item>
-        <item>@drawable/ic_lockscreen_silent</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_when_soundon">
-        <item>@string/description_target_unlock</item>
-        <item>@string/description_target_search</item>
-        <item>@string/description_target_silent</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_targets_with_camera">
-        <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@drawable/ic_action_assist_generic</item>
-        <item>@drawable/ic_lockscreen_camera</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_with_camera">
-        <item>@string/description_target_unlock</item>
-        <item>@string/description_target_search</item>
-        <item>@string/description_target_camera</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_targets_unlock_only">
-        <item>@drawable/ic_lockscreen_unlock</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_unlock_only">
-        <item>@string/description_target_unlock</item>
-    </array>
-
     <!-- list of 3- or 4-letter mnemonics for a 10-key numeric keypad -->
     <string-array translatable="false" name="lockscreen_num_pad_klondike">
         <item>+</item><!-- 0 -->
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
index 724b560..1835b8e 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -73,16 +73,22 @@
 
     @Override
     public void onResume(int reason) {
-        getSecurityView(mCurrentSecuritySelection).onResume(reason);
+        if (mCurrentSecuritySelection != SecurityMode.None) {
+            getSecurityView(mCurrentSecuritySelection).onResume(reason);
+        }
     }
 
     @Override
     public void onPause() {
-        getSecurityView(mCurrentSecuritySelection).onPause();
+        if (mCurrentSecuritySelection != SecurityMode.None) {
+            getSecurityView(mCurrentSecuritySelection).onPause();
+        }
     }
 
     public void startAppearAnimation() {
-        getSecurityView(mCurrentSecuritySelection).startAppearAnimation();
+        if (mCurrentSecuritySelection != SecurityMode.None) {
+            getSecurityView(mCurrentSecuritySelection).startAppearAnimation();
+        }
     }
 
     void updateSecurityViews(boolean isBouncing) {
@@ -119,12 +125,6 @@
             view = (KeyguardSecurityView)v;
         }
 
-        if (view instanceof KeyguardSelectorView) {
-            KeyguardSelectorView selectorView = (KeyguardSelectorView) view;
-            View carrierText = selectorView.findViewById(R.id.keyguard_selector_fade_container);
-            selectorView.setCarrierArea(carrierText);
-        }
-
         return view;
     }
 
@@ -378,8 +378,10 @@
             oldView.onPause();
             oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
         }
-        newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
-        newView.setKeyguardCallback(mCallback);
+        if (securityMode != SecurityMode.None) {
+            newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
+            newView.setKeyguardCallback(mCallback);
+        }
 
         // Find and show this child.
         final int childCount = mSecurityViewFlipper.getChildCount();
@@ -393,7 +395,8 @@
         }
 
         mCurrentSecuritySelection = securityMode;
-        mSecurityCallback.onSecurityModeChanged(securityMode, newView.needsInput());
+        mSecurityCallback.onSecurityModeChanged(securityMode,
+                securityMode != SecurityMode.None && newView.needsInput());
     }
 
     private KeyguardSecurityViewFlipper getFlipper() {
@@ -475,7 +478,6 @@
 
     private int getSecurityViewIdForMode(SecurityMode securityMode) {
         switch (securityMode) {
-            case None: return R.id.keyguard_selector_view;
             case Pattern: return R.id.keyguard_pattern_view;
             case PIN: return R.id.keyguard_pin_view;
             case Password: return R.id.keyguard_password_view;
@@ -489,7 +491,6 @@
 
     private int getLayoutIdFor(SecurityMode securityMode) {
         switch (securityMode) {
-            case None: return R.layout.keyguard_selector_view;
             case Pattern: return R.layout.keyguard_pattern_view;
             case PIN: return R.layout.keyguard_pin_view;
             case Password: return R.layout.keyguard_password_view;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
deleted file mode 100644
index 85bd87d..0000000
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.keyguard;
-
-import android.animation.ObjectAnimator;
-import android.app.SearchManager;
-import android.app.admin.DevicePolicyManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Slog;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import com.android.internal.telephony.IccCardConstants.State;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.multiwaveview.GlowPadView;
-import com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener;
-
-public class KeyguardSelectorView extends LinearLayout implements KeyguardSecurityView {
-    private static final String TAG = "SecuritySelectorView";
-    private static final String ASSIST_ICON_METADATA_NAME =
-        "com.android.systemui.action_assist_icon";
-
-    private KeyguardSecurityCallback mCallback;
-    private GlowPadView mGlowPadView;
-    private ObjectAnimator mAnim;
-    private View mFadeView;
-    private boolean mIsBouncing;
-    private boolean mCameraDisabled;
-    private boolean mSearchDisabled;
-    private LockPatternUtils mLockPatternUtils;
-    private SecurityMessageDisplay mSecurityMessageDisplay;
-    private Drawable mBouncerFrame;
-
-    OnTriggerListener mOnTriggerListener = new OnTriggerListener() {
-
-        public void onTrigger(View v, int target) {
-            final int resId = mGlowPadView.getResourceIdForTarget(target);
-
-            if (resId == R.drawable.ic_lockscreen_unlock_phantom
-                    || resId == R.drawable.ic_lockscreen_unlock) {
-                mCallback.userActivity();
-                mCallback.dismiss(false);
-            }
-        }
-
-        public void onReleased(View v, int handle) {
-            if (!mIsBouncing) {
-                doTransition(mFadeView, 1.0f);
-            }
-        }
-
-        public void onGrabbed(View v, int handle) {
-            mCallback.userActivity();
-            doTransition(mFadeView, 0.0f);
-        }
-
-        public void onGrabbedStateChange(View v, int handle) {
-
-        }
-
-        public void onFinishFinalAnimation() {
-
-        }
-
-    };
-
-    KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
-
-        @Override
-        public void onDevicePolicyManagerStateChanged() {
-            updateTargets();
-        }
-
-        @Override
-        public void onSimStateChanged(State simState) {
-            updateTargets();
-        }
-    };
-
-    public KeyguardSelectorView(Context context) {
-        this(context, null);
-    }
-
-    public KeyguardSelectorView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mLockPatternUtils = new LockPatternUtils(getContext());
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mGlowPadView = (GlowPadView) findViewById(R.id.glow_pad_view);
-        mGlowPadView.setOnTriggerListener(mOnTriggerListener);
-        updateTargets();
-
-        mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
-        View bouncerFrameView = findViewById(R.id.keyguard_selector_view_frame);
-        mBouncerFrame = bouncerFrameView.getBackground();
-    }
-
-    public void setCarrierArea(View carrierArea) {
-        mFadeView = carrierArea;
-    }
-
-    public boolean isTargetPresent(int resId) {
-        return mGlowPadView.getTargetPosition(resId) != -1;
-    }
-
-    @Override
-    public void showUsabilityHint() {
-        mGlowPadView.ping();
-    }
-
-    private void updateTargets() {
-        int currentUserHandle = mLockPatternUtils.getCurrentUser();
-        DevicePolicyManager dpm = mLockPatternUtils.getDevicePolicyManager();
-        int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUserHandle);
-        boolean secureCameraDisabled = mLockPatternUtils.isSecure()
-                && (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0;
-        boolean cameraDisabledByAdmin = dpm.getCameraDisabled(null, currentUserHandle)
-                || secureCameraDisabled;
-        final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(getContext());
-        boolean disabledBySimState = monitor.isSimLocked();
-        boolean cameraTargetPresent =
-            isTargetPresent(R.drawable.ic_lockscreen_camera);
-        boolean searchTargetPresent =
-            isTargetPresent(R.drawable.ic_action_assist_generic);
-
-        if (cameraDisabledByAdmin) {
-            Log.v(TAG, "Camera disabled by Device Policy");
-        } else if (disabledBySimState) {
-            Log.v(TAG, "Camera disabled by Sim State");
-        }
-        boolean currentUserSetup = 0 != Settings.Secure.getIntForUser(
-                mContext.getContentResolver(),
-                Settings.Secure.USER_SETUP_COMPLETE,
-                0 /*default */,
-                currentUserHandle);
-        boolean searchActionAvailable =
-                ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
-                .getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
-        mCameraDisabled = cameraDisabledByAdmin || disabledBySimState || !cameraTargetPresent
-                || !currentUserSetup;
-        mSearchDisabled = disabledBySimState || !searchActionAvailable || !searchTargetPresent
-                || !currentUserSetup;
-        updateResources();
-    }
-
-    public void updateResources() {
-        // Update the search icon with drawable from the search .apk
-        if (!mSearchDisabled) {
-            Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
-                    .getAssistIntent(mContext, false, UserHandle.USER_CURRENT);
-            if (intent != null) {
-                // XXX Hack. We need to substitute the icon here but haven't formalized
-                // the public API. The "_google" metadata will be going away, so
-                // DON'T USE IT!
-                ComponentName component = intent.getComponent();
-                boolean replaced = mGlowPadView.replaceTargetDrawablesIfPresent(component,
-                        ASSIST_ICON_METADATA_NAME + "_google", R.drawable.ic_action_assist_generic);
-
-                if (!replaced && !mGlowPadView.replaceTargetDrawablesIfPresent(component,
-                            ASSIST_ICON_METADATA_NAME, R.drawable.ic_action_assist_generic)) {
-                        Slog.w(TAG, "Couldn't grab icon from package " + component);
-                }
-            }
-        }
-
-        mGlowPadView.setEnableTarget(R.drawable.ic_lockscreen_camera, !mCameraDisabled);
-        mGlowPadView.setEnableTarget(R.drawable.ic_action_assist_generic, !mSearchDisabled);
-    }
-
-    void doTransition(View view, float to) {
-        if (mAnim != null) {
-            mAnim.cancel();
-        }
-        mAnim = ObjectAnimator.ofFloat(view, "alpha", to);
-        mAnim.start();
-    }
-
-    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
-        mCallback = callback;
-    }
-
-    public void setLockPatternUtils(LockPatternUtils utils) {
-        mLockPatternUtils = utils;
-    }
-
-    @Override
-    public void reset() {
-        mGlowPadView.reset(false);
-    }
-
-    @Override
-    public boolean needsInput() {
-        return false;
-    }
-
-    @Override
-    public void onPause() {
-        KeyguardUpdateMonitor.getInstance(getContext()).removeCallback(mUpdateCallback);
-    }
-
-    @Override
-    public void onResume(int reason) {
-        KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mUpdateCallback);
-    }
-
-    @Override
-    public KeyguardSecurityCallback getCallback() {
-        return mCallback;
-    }
-
-    @Override
-    public void showBouncer(int duration) {
-        mIsBouncing = true;
-        KeyguardSecurityViewHelper.
-                showBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration);
-    }
-
-    @Override
-    public void hideBouncer(int duration) {
-        mIsBouncing = false;
-        KeyguardSecurityViewHelper.
-                hideBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration);
-    }
-
-    @Override
-    public void startAppearAnimation() {
-        // noop.
-    }
-}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index e4d7850..58cbaba 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -83,6 +83,11 @@
     private static final int FAILED_BIOMETRIC_UNLOCK_ATTEMPTS_BEFORE_BACKUP = 3;
     private static final int LOW_BATTERY_THRESHOLD = 20;
 
+    private static final String ACTION_FACE_UNLOCK_STARTED
+            = "com.android.facelock.FACE_UNLOCK_STARTED";
+    private static final String ACTION_FACE_UNLOCK_STOPPED
+            = "com.android.facelock.FACE_UNLOCK_STOPPED";
+
     // Callback messages
     private static final int MSG_TIME_UPDATE = 301;
     private static final int MSG_BATTERY_UPDATE = 302;
@@ -107,6 +112,7 @@
     private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
     private static final int MSG_FINGERPRINT_PROCESSED = 323;
     private static final int MSG_FINGERPRINT_ACQUIRED = 324;
+    private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 325;
 
     private static KeyguardUpdateMonitor sInstance;
 
@@ -211,6 +217,9 @@
                 case MSG_FINGERPRINT_PROCESSED:
                     handleFingerprintProcessed(msg.arg1);
                     break;
+                case MSG_FACE_UNLOCK_STATE_CHANGED:
+                    handleFaceUnlockStateChanged(msg.arg1 != 0);
+                    break;
             }
         }
     };
@@ -285,6 +294,15 @@
         }
     }
 
+    private void handleFaceUnlockStateChanged(boolean running) {
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onFaceUnlockStateChanged(running);
+            }
+        }
+    }
+
     private boolean isTrustDisabled(int userId) {
         final DevicePolicyManager dpm =
                 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
@@ -376,6 +394,10 @@
                        intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0), 0));
             } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
                 dispatchBootCompleted();
+            } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1, 0));
+            } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0, 0));
             }
         }
     };
@@ -588,6 +610,8 @@
         filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
         filter.addAction(Intent.ACTION_USER_REMOVED);
         filter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
+        filter.addAction(ACTION_FACE_UNLOCK_STARTED);
+        filter.addAction(ACTION_FACE_UNLOCK_STOPPED);
         context.registerReceiver(mBroadcastReceiver, filter);
 
         final IntentFilter bootCompleteFilter = new IntentFilter();
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 0aefa2d..4827e79 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -188,4 +188,9 @@
      * Called when fingerprint is acquired but not yet recognized
      */
     public void onFingerprintAcquired(int info) { }
+
+    /**
+     * Called when the state of face unlock changed.
+     */
+    public void onFaceUnlockStateChanged(boolean running) { }
 }
diff --git a/packages/PrintSpooler/res/values-hi/strings.xml b/packages/PrintSpooler/res/values-hi/strings.xml
index 52a018f..581995a 100644
--- a/packages/PrintSpooler/res/values-hi/strings.xml
+++ b/packages/PrintSpooler/res/values-hi/strings.xml
@@ -35,7 +35,7 @@
     <string name="generating_print_job" msgid="3119608742651698916">"प्रिंट कार्य जनरेट हो रहा है"</string>
     <string name="save_as_pdf" msgid="5718454119847596853">"PDF के रूप में सहेजें"</string>
     <string name="all_printers" msgid="5018829726861876202">"सभी प्रिंटर..."</string>
-    <string name="print_dialog" msgid="32628687461331979">"प्रिंट संवाद"</string>
+    <string name="print_dialog" msgid="32628687461331979">"प्रिंट डॉयलॉग"</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="search" msgid="5421724265322228497">"खोजें"</string>
     <string name="all_printers_label" msgid="3178848870161526399">"सभी प्रिंटर"</string>
diff --git a/packages/PrintSpooler/res/values/themes.xml b/packages/PrintSpooler/res/values/themes.xml
index 7d0da14..db319e9 100644
--- a/packages/PrintSpooler/res/values/themes.xml
+++ b/packages/PrintSpooler/res/values/themes.xml
@@ -16,16 +16,13 @@
 
 <resources>
 
-    <style name="PrintActivity" parent="@android:style/Theme.Material">
+    <style name="PrintActivity" parent="@android:style/Theme.Material.Settings">
         <item name="android:windowIsTranslucent">true</item>
         <item name="android:windowBackground">@android:color/transparent</item>
         <item name="android:windowContentOverlay">@null</item>
         <item name="android:windowActionBar">false</item>
         <item name="android:windowNoTitle">true</item>
         <item name="android:backgroundDimEnabled">false</item>
-        <item name="android:colorPrimary">@*android:color/material_blue_grey_900</item>
-        <item name="android:colorPrimaryDark">@*android:color/material_blue_grey_950</item>
-        <item name="android:colorAccent">@*android:color/material_dark_teal_A400</item>
     </style>
 
 </resources>
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index a92ab7e..478a5de 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -183,7 +183,7 @@
     <!-- Default for Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE -->
     <integer name="def_wifi_scan_always_available">0</integer>
 
-    <!-- Default for Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1==on -->
+    <!-- Default for Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1==on -->
     <integer name="def_lock_screen_show_notifications">1</integer>
 
     <!-- Default for Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED, 1==on -->
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 09e6a94..7c92cde 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -70,7 +70,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 105;
+    private static final int DATABASE_VERSION = 106;
 
     private Context mContext;
     private int mUserHandle;
@@ -1558,24 +1558,17 @@
         }
 
         if (upgradeVersion == 98) {
-            if (mUserHandle == UserHandle.USER_OWNER) {
-                db.beginTransaction();
-                SQLiteStatement stmt = null;
-                try {
-                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
-                            + " VALUES(?,?);");
-                    loadIntegerSetting(stmt, Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS,
-                            R.integer.def_lock_screen_show_notifications);
-                    db.setTransactionSuccessful();
-                } finally {
-                    db.endTransaction();
-                    if (stmt != null) stmt.close();
-                }
-            }
+            // no-op; LOCK_SCREEN_SHOW_NOTIFICATIONS now handled in version 106
             upgradeVersion = 99;
         }
 
         if (upgradeVersion == 99) {
+            // no-op; HEADS_UP_NOTIFICATIONS_ENABLED now handled in version 100
+            upgradeVersion = 100;
+        }
+
+        if (upgradeVersion == 100) {
+            // note: LOCK_SCREEN_SHOW_NOTIFICATIONS now handled in version 106
             if (mUserHandle == UserHandle.USER_OWNER) {
                 db.beginTransaction();
                 SQLiteStatement stmt = null;
@@ -1590,28 +1583,6 @@
                     if (stmt != null) stmt.close();
                 }
             }
-            upgradeVersion = 100;
-        }
-        if (upgradeVersion == 100) {
-           // Catch devices that were initialized to version 100 and missed these in onCreate()
-            if (mUserHandle == UserHandle.USER_OWNER) {
-                db.beginTransaction();
-                SQLiteStatement stmt = null;
-                try {
-                    stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"
-                            + " VALUES(?,?);");
-                    loadIntegerSetting(stmt, Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS,
-                            R.integer.def_lock_screen_show_notifications);
-
-                    loadIntegerSetting(stmt, Global.HEADS_UP_NOTIFICATIONS_ENABLED,
-                            R.integer.def_heads_up_enabled);
-
-                    db.setTransactionSuccessful();
-                } finally {
-                    db.endTransaction();
-                    if (stmt != null) stmt.close();
-                }
-            }
             upgradeVersion = 101;
         }
 
@@ -1695,6 +1666,34 @@
             upgradeVersion = 105;
         }
 
+        if (upgradeVersion < 106) {
+            // LOCK_SCREEN_SHOW_NOTIFICATIONS is now per-user.
+            db.beginTransaction();
+            SQLiteStatement stmt = null;
+            try {
+                stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
+                        + " VALUES(?,?);");
+                loadBooleanSetting(stmt, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                        R.bool.def_guest_user_enabled);
+                if (mUserHandle == UserHandle.USER_OWNER) {
+                    final int oldShow = getIntValueFromTable(db,
+                            TABLE_GLOBAL, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, -1);
+                    if (oldShow >= 0) {
+                        // overwrite the default with whatever you had
+                        loadSetting(stmt, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, oldShow);
+                        final SQLiteStatement deleteStmt
+                                = db.compileStatement("DELETE FROM global WHERE name=?");
+                        deleteStmt.bindString(1, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
+                        deleteStmt.execute();
+                    }
+                }
+                db.setTransactionSuccessful();
+            } finally {
+                db.endTransaction();
+                if (stmt != null) stmt.close();
+            }
+            upgradeVersion = 106;
+        }
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
@@ -2260,6 +2259,9 @@
             loadBooleanSetting(stmt, Settings.Secure.WAKE_GESTURE_ENABLED,
                     R.bool.def_wake_gesture_enabled);
 
+            loadIntegerSetting(stmt, Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                    R.integer.def_lock_screen_show_notifications);
+
         } finally {
             if (stmt != null) stmt.close();
         }
@@ -2420,9 +2422,6 @@
             loadIntegerSetting(stmt, Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE,
                     R.integer.def_wifi_scan_always_available);
 
-            loadIntegerSetting(stmt, Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS,
-                    R.integer.def_lock_screen_show_notifications);
-
             loadIntegerSetting(stmt, Global.HEADS_UP_NOTIFICATIONS_ENABLED,
                     R.integer.def_heads_up_enabled);
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index dd7a828..91199c1 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -190,33 +190,34 @@
         String localeString = loc.getLanguage();
         String country = loc.getCountry();
         if (!TextUtils.isEmpty(country)) {
-            localeString += "_" + country;
+            localeString += "-" + country;
         }
         return localeString.getBytes();
     }
 
     /**
-     * Sets the locale specified. Input data is the equivalent of "ll_cc".getBytes(), where
-     * "ll" is the language code and "cc" is the country code.
+     * Sets the locale specified. Input data is the byte representation of a
+     * BCP-47 language tag. For backwards compatibility, strings of the form
+     * {@code ll_CC} are also accepted, where {@code ll} is a two letter language
+     * code and {@code CC} is a two letter country code.
+     *
      * @param data the locale string in bytes.
      */
     void setLocaleData(byte[] data, int size) {
         // Check if locale was set by the user:
         Configuration conf = mContext.getResources().getConfiguration();
-        Locale loc = conf.locale;
         // TODO: The following is not working as intended because the network is forcing a locale
         // change after registering. Need to find some other way to detect if the user manually
         // changed the locale
         if (conf.userSetLocale) return; // Don't change if user set it in the SetupWizard
 
         final String[] availableLocales = mContext.getAssets().getLocales();
-        String localeCode = new String(data, 0, size);
-        String language = new String(data, 0, 2);
-        String country = size > 4 ? new String(data, 3, 2) : "";
-        loc = null;
+        // Replace "_" with "-" to deal with older backups.
+        String localeCode = new String(data, 0, size).replace('_', '-');
+        Locale loc = null;
         for (int i = 0; i < availableLocales.length; i++) {
             if (availableLocales[i].equals(localeCode)) {
-                loc = new Locale(language, country);
+                loc = Locale.forLanguageTag(localeCode);
                 break;
             }
         }
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_action_assist_generic_activated.png b/packages/SystemUI/res/drawable-hdpi/ic_action_assist_generic_activated.png
deleted file mode 100644
index c0e2098..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_action_assist_generic_activated.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_action_assist_generic_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_action_assist_generic_normal.png
deleted file mode 100644
index a852e2c..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_action_assist_generic_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_in.png
deleted file mode 100644
index 250653b..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_inout.png
deleted file mode 100644
index 497c69f..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_out.png
deleted file mode 100644
index d750726..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_in.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_in.png
deleted file mode 100644
index 250653b..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_inout.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_inout.png
deleted file mode 100644
index 497c69f..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_out.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_out.png
deleted file mode 100644
index d750726..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land/search_panel_scrim.xml b/packages/SystemUI/res/drawable-land/search_panel_scrim.xml
new file mode 100644
index 0000000..102cc9c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-land/search_panel_scrim.xml
@@ -0,0 +1,25 @@
+<?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
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+            android:type="linear"
+            android:angle="180"
+            android:startColor="#55000000"
+            android:endColor="#00000000" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_in.png
deleted file mode 100644
index 64c6723..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_inout.png
deleted file mode 100644
index 2338122..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_out.png
deleted file mode 100644
index 29df6d7..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_in.png
deleted file mode 100644
index 3fba731..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_inout.png
deleted file mode 100644
index eb5fcd0..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_out.png
deleted file mode 100644
index a91c7c7..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_in.png
deleted file mode 100644
index 521de12..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_inout.png
deleted file mode 100644
index 4d015da..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_out.png
deleted file mode 100644
index d8209e6..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_in.png
deleted file mode 100644
index 3725b3f..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_inout.png
deleted file mode 100644
index b72a274..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_out.png
deleted file mode 100644
index aa2de43..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_action_assist_generic_activated.png b/packages/SystemUI/res/drawable-mdpi/ic_action_assist_generic_activated.png
deleted file mode 100644
index f88f7e1..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_action_assist_generic_activated.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_action_assist_generic_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_action_assist_generic_normal.png
deleted file mode 100644
index 7426994..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_action_assist_generic_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_in.png
deleted file mode 100644
index 4a2119f..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_inout.png
deleted file mode 100644
index a53d764..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_out.png
deleted file mode 100644
index 8b7251b..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_in.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_in.png
deleted file mode 100644
index 4a2119f..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_inout.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_inout.png
deleted file mode 100644
index a53d764..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_out.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_out.png
deleted file mode 100644
index 8b7251b..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp/search_panel_scrim.xml b/packages/SystemUI/res/drawable-sw600dp/search_panel_scrim.xml
new file mode 100644
index 0000000..bbb2617
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp/search_panel_scrim.xml
@@ -0,0 +1,25 @@
+<?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
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+            android:type="linear"
+            android:angle="90"
+            android:startColor="#55000000"
+            android:endColor="#00000000" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_action_assist_generic_activated.png b/packages/SystemUI/res/drawable-xhdpi/ic_action_assist_generic_activated.png
deleted file mode 100644
index 500b157..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_action_assist_generic_activated.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_action_assist_generic_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_action_assist_generic_normal.png
deleted file mode 100644
index d0e4cf3..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_action_assist_generic_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_in.png
deleted file mode 100644
index 1664688..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_inout.png
deleted file mode 100644
index b38e3ef..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_out.png
deleted file mode 100644
index c645859..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_in.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_in.png
deleted file mode 100644
index 1664688..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_inout.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_inout.png
deleted file mode 100644
index b38e3ef..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_out.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_out.png
deleted file mode 100644
index c645859..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_action_assist_generic_activated.png b/packages/SystemUI/res/drawable-xxhdpi/ic_action_assist_generic_activated.png
deleted file mode 100644
index cc38e83..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_action_assist_generic_activated.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_action_assist_generic_normal.png b/packages/SystemUI/res/drawable-xxhdpi/ic_action_assist_generic_normal.png
deleted file mode 100644
index 42f96eb..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_action_assist_generic_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_in.png
deleted file mode 100644
index 3725b3f..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_inout.png
deleted file mode 100644
index b72a274..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_out.png
deleted file mode 100644
index aa2de43..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_in.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_in.png
deleted file mode 100644
index 5b80893..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_inout.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_inout.png
deleted file mode 100644
index 21b2118..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_out.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_out.png
deleted file mode 100644
index 3f0447d..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_action_assist_generic.xml b/packages/SystemUI/res/drawable/ic_action_assist_generic.xml
deleted file mode 100644
index 60f5d5d..0000000
--- a/packages/SystemUI/res/drawable/ic_action_assist_generic.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <item
-        android:state_enabled="true"
-        android:state_active="false"
-        android:state_focused="false"
-        android:drawable="@drawable/ic_action_assist_generic_normal" />
-
-    <item
-        android:state_enabled="true"
-        android:state_active="true"
-        android:state_focused="false"
-        android:drawable="@drawable/ic_action_assist_generic_activated" />
-
-    <item
-        android:state_enabled="true"
-        android:state_active="false"
-        android:state_focused="true"
-        android:drawable="@drawable/ic_action_assist_generic_activated" />
-
-</selector>
diff --git a/packages/SystemUI/res/drawable/ic_clear_all.xml b/packages/SystemUI/res/drawable/ic_dismiss_all.xml
similarity index 61%
rename from packages/SystemUI/res/drawable/ic_clear_all.xml
rename to packages/SystemUI/res/drawable/ic_dismiss_all.xml
index 187a420..8e5e572 100644
--- a/packages/SystemUI/res/drawable/ic_clear_all.xml
+++ b/packages/SystemUI/res/drawable/ic_dismiss_all.xml
@@ -14,12 +14,17 @@
   ~ limitations under the License
   -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32dp"
-        android:height="32dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="48.0"
+    android:viewportHeight="48.0">
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M10.0,26.0l28.0,0.0l0.0,-4.0L10.0,22.0L10.0,26.0zM6.0,34.0l28.0,0.0l0.0,-4.0L6.0,30.0L6.0,34.0zM14.0,14.0l0.0,4.0l28.0,0.0l0.0,-4.0L14.0,14.0z"/>
+        android:fillColor="#ffffff"
+        android:pathData="M8.0,19.994l32.0,0.0l0.0,8.0l-32.0,0.0z"/>
+    <path
+        android:fillColor="#ffffff"
+        android:pathData="M0.0,32.0l32.0,0.0l0.0,7.979l-32.0,0.0z"/>
+    <path
+        android:fillColor="#ffffff"
+        android:pathData="M16.0,8.0l32.0,0.0l0.0,8.0l-32.0,0.0z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_rotation_unlocked.xml b/packages/SystemUI/res/drawable/ic_qs_rotation_unlocked.xml
index 6872a33..94b3a6b 100644
--- a/packages/SystemUI/res/drawable/ic_qs_rotation_unlocked.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_rotation_unlocked.xml
@@ -18,14 +18,7 @@
         android:height="64dp"
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
-
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M10.25,1.75c-0.6,-0.6 -1.5,-0.6 -2.1,0.0l-6.4,6.4c-0.6,0.6 -0.6,1.5 0.0,2.1l12.0,12.0c0.6,0.6 1.5,0.6 2.1,0.0l6.4,-6.4c0.6,-0.6 0.6,-1.5 0.0,-2.1L10.25,1.75zM14.85,21.25l-12.0,-12.0l6.4,-6.4l12.0,12.0L14.85,21.25z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M16.55,2.5c3.3,1.5 5.6,4.7 6.0,8.5l1.5,0.0c-0.6,-6.2 -5.7,-11.0 -12.0,-11.0c-0.2,0.0 -0.4,0.0 -0.7,0.0l3.8,3.8L16.55,2.5z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M7.55,21.5c-3.3,-1.5 -5.6,-4.7 -6.0,-8.5l-1.4,0.0c0.5,6.2 5.6,11.0 11.9,11.0c0.2,0.0 0.4,0.0 0.7,0.0l-3.8,-3.8L7.55,21.5z"/>
+        android:pathData="M16.600000,2.500000c3.300000,1.500000 5.600000,4.700000 6.000000,8.500000l1.500000,0.000000c-0.600000,-6.200000 -5.700000,-11.000000 -12.000000,-11.000000c-0.200000,0.000000 -0.400000,0.000000 -0.700000,0.000000l3.800000,3.800000L16.600000,2.500000zM10.300000,1.700000c-0.600000,-0.600000 -1.500000,-0.600000 -2.100000,0.000000L1.800000,8.100000c-0.600000,0.600000 -0.600000,1.500000 0.000000,2.100000l12.000000,12.000000c0.600000,0.600000 1.500000,0.600000 2.100000,0.000000l6.400000,-6.400000c0.600000,-0.600000 0.600000,-1.500000 0.000000,-2.100000L10.300000,1.700000zM13.400000,19.700001l-9.200000,-9.200000l6.400000,-6.400000l9.200000,9.200000L13.400000,19.700001zM7.600000,21.500000C4.300000,20.000000 2.000000,16.799999 1.600000,13.000000L0.200000,13.000000c0.500000,6.200000 5.600000,11.000000 11.900000,11.000000c0.200000,0.000000 0.400000,0.000000 0.700000,0.000000L9.000000,20.200001L7.600000,21.500000z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml b/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml
index 8775264..71c40df 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml
@@ -14,15 +14,14 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:width="32dp"
+        android:width="16.0dp"
         android:height="32dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="12.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M4.300000,11.000000L2.700000,11.000000L2.700000,4.400000L1.000000,5.100000L1.000000,3.700000l3.100000,-1.300000l0.200000,0.000000L4.300000,11.000000z"/>
+        android:pathData="M3.500000,11.000000L1.800000,11.000000L1.800000,4.400000L0.200000,5.100000L0.200000,3.700000l3.100000,-1.300000l0.200000,0.000000L3.500000,11.000000z"/>
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M9.500000,5.500000l1.200000,-3.000000l1.900000,0.000000l-2.100000,4.200000l2.200000,4.300000l-1.900000,0.000000L9.500000,7.900000L8.300000,11.000000L6.300000,11.000000l2.100000,-4.300000L6.400000,2.500000l1.900000,0.000000L9.500000,5.500000z"/>
+        android:pathData="M8.600000,5.500000l1.200000,-3.000000l1.900000,0.000000L9.700000,6.700000l2.200000,4.300000L9.900000,11.000000L8.700000,7.900000L7.400000,11.000000L5.500000,11.000000l2.100000,-4.300000L5.600000,2.500000l1.900000,0.000000L8.600000,5.500000z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml b/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml
index 4b4e2e5..e9a57ea 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml
@@ -14,15 +14,14 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:width="32dp"
+        android:width="17.333334dp"
         android:height="32dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="13.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M2.600000,6.000000l0.800000,0.000000c0.300000,0.000000 0.500000,-0.100000 0.700000,-0.300000s0.200000,-0.500000 0.200000,-0.900000c0.000000,-0.300000 -0.100000,-0.600000 -0.200000,-0.800000S3.700000,3.700000 3.500000,3.700000C3.200000,3.700000 3.000000,3.800000 2.900000,4.000000S2.600000,4.400000 2.600000,4.700000L1.000000,4.700000C1.000000,4.000000 1.200000,3.400000 1.700000,3.000000s1.000000,-0.600000 1.700000,-0.600000c0.800000,0.000000 1.400000,0.200000 1.900000,0.600000S6.000000,4.000000 6.000000,4.800000c0.000000,0.400000 -0.100000,0.700000 -0.300000,1.100000S5.200000,6.500000 4.800000,6.600000c0.400000,0.200000 0.700000,0.400000 0.900000,0.800000s0.300000,0.700000 0.300000,1.200000c0.000000,0.800000 -0.200000,1.400000 -0.700000,1.800000s-1.100000,0.700000 -1.900000,0.700000c-0.700000,0.000000 -1.300000,-0.200000 -1.800000,-0.600000s-0.700000,-1.000000 -0.700000,-1.800000l1.700000,0.000000c0.000000,0.300000 0.100000,0.600000 0.300000,0.800000s0.400000,0.300000 0.600000,0.300000c0.300000,0.000000 0.500000,-0.100000 0.700000,-0.300000S4.400000,9.000000 4.400000,8.600000c0.000000,-0.500000 -0.100000,-0.800000 -0.300000,-1.000000S3.700000,7.300000 3.400000,7.300000L2.600000,7.300000L2.600000,6.000000z"/>
+        android:pathData="M2.000000,6.000000l0.800000,0.000000c0.300000,0.000000 0.500000,-0.100000 0.700000,-0.300000s0.200000,-0.500000 0.200000,-0.900000c0.000000,-0.300000 -0.100000,-0.600000 -0.200000,-0.800000S3.200000,3.700000 2.900000,3.700000C2.700000,3.700000 2.500000,3.800000 2.300000,4.000000S2.100000,4.400000 2.100000,4.700000L0.500000,4.700000C0.500000,4.000000 0.700000,3.400000 1.100000,3.000000s1.000000,-0.600000 1.700000,-0.600000c0.800000,0.000000 1.400000,0.200000 1.900000,0.600000s0.700000,1.000000 0.700000,1.800000c0.000000,0.400000 -0.100000,0.700000 -0.300000,1.100000S4.600000,6.500000 4.300000,6.600000C4.700000,6.800000 5.000000,7.100000 5.200000,7.400000s0.300000,0.700000 0.300000,1.200000c0.000000,0.800000 -0.200000,1.400000 -0.700000,1.800000s-1.100000,0.700000 -1.900000,0.700000c-0.700000,0.000000 -1.300000,-0.200000 -1.800000,-0.600000s-0.700000,-1.000000 -0.700000,-1.800000L2.000000,8.700000C2.000000,9.000000 2.100000,9.300000 2.300000,9.500000s0.400000,0.300000 0.600000,0.300000c0.300000,0.000000 0.500000,-0.100000 0.700000,-0.300000S3.900000,9.000000 3.900000,8.600000c0.000000,-0.500000 -0.100000,-0.800000 -0.300000,-1.000000S3.200000,7.300000 2.800000,7.300000L2.000000,7.300000L2.000000,6.000000z"/>
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M13.100000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S7.300000,9.000000 7.300000,7.900000L7.300000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000s1.200000,-0.800000 2.100000,-0.800000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000S13.000000,4.200000 13.000000,5.100000l-1.600000,0.000000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000s-0.500000,-0.300000 -0.900000,-0.300000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S8.900000,5.000000 8.900000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L11.299999,7.800000l-1.300000,0.000000L9.999999,6.600000l2.900000,0.000000L12.900000,9.900000z"/>
+        android:pathData="M12.500000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S6.700000,9.000000 6.700000,7.900000L6.700000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000s1.200000,-0.800000 2.100000,-0.800000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000l-1.600000,0.000000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000s-0.500000,-0.300000 -0.900000,-0.300000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S8.400000,5.000000 8.400000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L10.799999,7.800000L9.600000,7.800000L9.600000,6.600000l2.900000,0.000000L12.500000,9.900000z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml b/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml
index 920692f..42045d1 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml
@@ -14,15 +14,14 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:width="32dp"
+        android:width="16.0dp"
         android:height="32dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="12.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M5.700000,7.800000l0.700000,0.000000l0.000000,1.300000L5.700000,9.100000L5.700000,11.000000L4.000000,11.000000L4.000000,9.200000L1.200000,9.200000l-0.100000,-1.000000L4.000000,2.500000l1.700000,0.000000L5.700000,7.800000zM2.700000,7.800000L4.000000,7.800000l0.000000,-3.000000L4.000000,5.000000L2.700000,7.800000z"/>
+        android:pathData="M4.600000,7.800000l0.700000,0.000000l0.000000,1.300000L4.600000,9.100000L4.600000,11.000000L3.000000,11.000000L3.000000,9.200000L0.100000,9.200000L0.000000,8.100000L3.000000,2.500000l1.700000,0.000000L4.700000,7.800000zM1.600000,7.800000L3.000000,7.800000l0.000000,-3.000000L2.900000,5.000000L1.600000,7.800000z"/>
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M13.000000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S7.200000,9.000000 7.200000,7.900000L7.200000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000s1.200000,-0.800000 2.100000,-0.800000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000l-1.600000,0.000000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000s-0.500000,-0.300000 -0.900000,-0.300000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S8.800000,5.000000 8.800000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L11.200000,7.800000l-1.300000,0.000000L9.900000,6.600000L13.000000,6.600000L13.000000,9.900000z"/>
+        android:pathData="M11.900000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S6.100000,9.000000 6.100000,7.900000L6.100000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000S8.100000,2.400000 9.000000,2.400000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000l-1.600000,0.000000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000S9.500000,3.700000 9.000000,3.700000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S7.700000,5.000000 7.700000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L10.099999,7.800000L9.000000,7.800000L9.000000,6.600000l2.900000,0.000000L11.900000,9.900000z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_disabled.xml b/packages/SystemUI/res/drawable/ic_qs_signal_disabled.xml
new file mode 100644
index 0000000..4f253e3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_disabled.xml
@@ -0,0 +1,28 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:autoMirrored="true"
+        android:width="32dp"
+        android:height="32dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#4DFFFFFF"
+        android:pathData="M21.799999,22.299999l-1.199999,-1.299999 0.000000,0.000000 -9.600000,-10.000000 0.000000,0.000000 -6.400000,-6.700000 -1.300000,1.300000 6.400000,6.700000 -8.700000,8.700000 16.900000,0.000000 2.600000,2.700001z"/>
+    <path
+        android:fillColor="#4DFFFFFF"
+        android:pathData="M21.000000,1.000000l-8.600000,8.600000 8.600000,9.100000z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_e.xml b/packages/SystemUI/res/drawable/ic_qs_signal_e.xml
index 737f2d8..e49a409 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_e.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_e.xml
@@ -14,12 +14,11 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:width="32dp"
+        android:width="6.6666665dp"
         android:height="32dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="5.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M5.900000,7.300000L3.100000,7.300000l0.000000,2.400000l3.300000,0.000000L6.400000,11.000000L1.400000,11.000000L1.400000,2.500000l4.900000,0.000000l0.000000,1.300000L3.100000,3.800000l0.000000,2.100000l2.800000,0.000000L5.900000,7.300000z"/>
+        android:pathData="M4.400000,7.300000L1.700000,7.300000l0.000000,2.400000l3.300000,0.000000L5.000000,11.000000L0.000000,11.000000L0.000000,2.500000l4.900000,0.000000l0.000000,1.300000L1.700000,3.800000l0.000000,2.100000l2.800000,0.000000L4.500000,7.300000z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_g.xml b/packages/SystemUI/res/drawable/ic_qs_signal_g.xml
index b0f3c0f..9d42a44 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_g.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_g.xml
@@ -14,12 +14,11 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:width="32dp"
+        android:width="9.333333dp"
         android:height="32dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="7.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M7.500000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S1.700000,9.000000 1.700000,7.900000L1.700000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000s1.200000,-0.800000 2.100000,-0.800000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000L5.700000,5.200000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000S5.000000,3.700000 4.600000,3.700000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S3.300000,5.000000 3.300000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L5.700000,7.800000L4.500000,7.800000L4.500000,6.600000l2.900000,0.000000L7.400000,9.900000z"/>
+        android:pathData="M6.500000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S0.700000,9.000000 0.700000,7.900000L0.700000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000s1.200000,-0.800000 2.100000,-0.800000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000L4.700000,5.200000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000S4.000000,3.700000 3.600000,3.700000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S2.300000,5.000000 2.300000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L4.700000,7.800000L3.500000,7.800000L3.500000,6.600000l2.900000,0.000000L6.400000,9.900000z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_h.xml b/packages/SystemUI/res/drawable/ic_qs_signal_h.xml
index 8532b27..f509d71 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_h.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_h.xml
@@ -14,12 +14,11 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:width="32dp"
+        android:width="8.0dp"
         android:height="32dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="6.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M7.700000,11.000000L6.000000,11.000000L6.000000,7.500000L3.400000,7.500000L3.400000,11.000000L1.700000,11.000000L1.700000,2.500000l1.700000,0.000000l0.000000,3.700000L6.000000,6.200000L6.000000,2.500000l1.600000,0.000000L7.600000,11.000000z"/>
+        android:pathData="M6.000000,11.000000L4.400000,11.000000L4.400000,7.500000L1.700000,7.500000L1.700000,11.000000L0.000000,11.000000L0.000000,2.500000l1.700000,0.000000l0.000000,3.700000l2.700000,0.000000L4.400000,2.500000L6.000000,2.500000L6.000000,11.000000z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_in.xml b/packages/SystemUI/res/drawable/ic_qs_signal_in.xml
new file mode 100644
index 0000000..236fdac
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_in.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="6.0dp"
+        android:height="32dp"
+        android:viewportWidth="6.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M6.000000,15.700000l-3.000000,5.599999 -3.000000,-5.599999z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml b/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml
index ec273ed..b7242e6 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml
@@ -14,10 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:width="32dp"
+        android:width="17.333334dp"
         android:height="32dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="13.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_out.xml b/packages/SystemUI/res/drawable/ic_qs_signal_out.xml
new file mode 100644
index 0000000..c510972
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_out.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="6.0dp"
+        android:height="32dp"
+        android:viewportWidth="6.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M0.000000,13.700000l3.000000,-5.700000 3.000000,5.700000z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_r.xml b/packages/SystemUI/res/drawable/ic_qs_signal_r.xml
index bbf2761..66f64c9 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_r.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_r.xml
@@ -14,12 +14,11 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:width="32dp"
+        android:width="8.0dp"
         android:height="32dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="6.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M4.100000,7.900000l-1.000000,0.000000L3.100000,11.000000L1.400000,11.000000L1.400000,2.500000l2.700000,0.000000c0.900000,0.000000 1.500000,0.200000 2.000000,0.700000s0.700000,1.100000 0.700000,1.900000c0.000000,0.600000 -0.100000,1.100000 -0.300000,1.500000S6.000000,7.200000 5.600000,7.400000l1.500000,3.500000L7.100000,11.000000L5.400000,11.000000L4.100000,7.900000zM3.100000,6.500000l1.100000,0.000000c0.400000,0.000000 0.600000,-0.100000 0.800000,-0.400000s0.300000,-0.600000 0.300000,-1.000000c0.000000,-0.400000 -0.100000,-0.800000 -0.300000,-1.000000S4.600000,3.800000 4.200000,3.800000L3.100000,3.800000L3.100000,6.500000z"/>
+        android:pathData="M2.800000,7.900000l-1.000000,0.000000L1.800000,11.000000L0.200000,11.000000L0.200000,2.500000l2.700000,0.000000c0.900000,0.000000 1.500000,0.200000 2.000000,0.700000s0.700000,1.100000 0.700000,1.900000c0.000000,0.600000 -0.100000,1.100000 -0.300000,1.500000S4.800000,7.200000 4.400000,7.400000l1.500000,3.500000L5.900000,11.000000L4.100000,11.000000L2.800000,7.900000zM1.800000,6.500000l1.100000,0.000000c0.400000,0.000000 0.600000,-0.100000 0.800000,-0.400000S4.000000,5.600000 4.000000,5.200000c0.000000,-0.400000 -0.100000,-0.800000 -0.300000,-1.000000S3.300000,3.800000 2.900000,3.800000L1.800000,3.800000L1.800000,6.500000z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_vpn.xml b/packages/SystemUI/res/drawable/ic_qs_vpn.xml
new file mode 100644
index 0000000..e9141ef
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_vpn.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="12.0dp"
+        android:height="12.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+
+    <path
+        android:fillColor="#4DFFFFFF"
+        android:pathData="M22.000000,4.000000L22.000000,3.500000C22.000000,2.100000 20.900000,1.000000 19.500000,1.000000C18.100000,1.000000 17.000000,2.100000 17.000000,3.500000L17.000000,4.000000c-0.600000,0.000000 -1.000000,0.400000 -1.000000,1.000000l0.000000,4.000000c0.000000,0.600000 0.400000,1.000000 1.000000,1.000000l5.000000,0.000000c0.600000,0.000000 1.000000,-0.400000 1.000000,-1.000000L23.000000,5.000000C23.000000,4.400000 22.600000,4.000000 22.000000,4.000000zM21.200001,4.000000l-3.400000,0.000000L17.800001,3.500000c0.000000,-0.900000 0.800000,-1.700000 1.700000,-1.700000c0.900000,0.000000 1.700000,0.800000 1.700000,1.700000L21.200003,4.000000zM18.900000,12.000000c0.000000,0.300000 0.100000,0.700000 0.100000,1.000000c0.000000,2.100000 -0.800000,4.000000 -2.100000,5.400000c-0.300000,-0.800000 -1.000000,-1.400000 -1.900000,-1.400000l-1.000000,0.000000l0.000000,-3.000000c0.000000,-0.600000 -0.400000,-1.000000 -1.000000,-1.000000L7.000000,13.000000l0.000000,-2.000000l2.000000,0.000000c0.600000,0.000000 1.000000,-0.400000 1.000000,-1.000000L10.000000,8.000000l2.000000,0.000000c1.100000,0.000000 2.000000,-0.900000 2.000000,-2.000000L14.000000,3.500000C13.100000,3.200000 12.000000,3.000000 11.000000,3.000000C5.500000,3.000000 1.000000,7.500000 1.000000,13.000000c0.000000,5.500000 4.500000,10.000000 10.000000,10.000000c5.500000,0.000000 10.000000,-4.500000 10.000000,-10.000000c0.000000,-0.300000 0.000000,-0.700000 -0.100000,-1.000000L18.900000,12.000000zM10.000000,20.900000c-3.900000,-0.500000 -7.000000,-3.900000 -7.000000,-7.900000c0.000000,-0.600000 0.100000,-1.200000 0.200000,-1.800000L8.000000,16.000000l0.000000,1.000000c0.000000,1.100000 0.900000,2.000000 2.000000,2.000000L10.000000,20.900000z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml
new file mode 100644
index 0000000..c505783
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml
@@ -0,0 +1,27 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="32.0dp"
+        android:height="29.5dp"
+        android:viewportWidth="26.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#4DFFFFFF"
+        android:pathData="M17.500000,16.500000L5.800000,3.400000c0.000000,0.000000 0.000000,0.000000 0.000000,0.000000l-2.700000,-3.000000L1.600000,1.800000l2.200000,2.500000c-2.000000,1.000000 -3.200000,2.000000 -3.400000,2.200000L13.000000,22.000000l0.000000,0.000000l0.000000,0.000000l0.000000,0.000000l0.000000,0.000000l3.200000,-3.900000l2.400000,2.700000l1.500000,-1.400000L17.500000,16.500000L17.500000,16.500000z"/>
+    <path
+        android:fillColor="#4DFFFFFF"
+        android:pathData="M25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000c-1.900000,0.000000 -3.600000,0.300000 -5.200000,0.700000L18.700001,15.000000L25.600000,6.500000z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/qs_detail_background.xml b/packages/SystemUI/res/drawable/qs_detail_background.xml
new file mode 100644
index 0000000..692cd44
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_detail_background.xml
@@ -0,0 +1,19 @@
+<!--
+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.
+-->
+<transition xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@color/qs_detail_transition" />
+    <item android:drawable="@color/system_primary_color" />
+</transition>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_navbar_scrim.xml b/packages/SystemUI/res/drawable/qs_navbar_scrim.xml
new file mode 100644
index 0000000..bbb2617
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_navbar_scrim.xml
@@ -0,0 +1,25 @@
+<?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
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+            android:type="linear"
+            android:angle="90"
+            android:startColor="#55000000"
+            android:endColor="#00000000" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/search_panel_card_bg.xml b/packages/SystemUI/res/drawable/search_panel_card_bg.xml
new file mode 100644
index 0000000..c19f900
--- /dev/null
+++ b/packages/SystemUI/res/drawable/search_panel_card_bg.xml
@@ -0,0 +1,21 @@
+<?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
+  -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/search_panel_card_color" />
+    <corners android:radius="@dimen/notification_material_rounded_rect_radius" />
+</shape>
diff --git a/packages/SystemUI/res/drawable/search_panel_scrim.xml b/packages/SystemUI/res/drawable/search_panel_scrim.xml
new file mode 100644
index 0000000..bbb2617
--- /dev/null
+++ b/packages/SystemUI/res/drawable/search_panel_scrim.xml
@@ -0,0 +1,25 @@
+<?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
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+            android:type="linear"
+            android:angle="90"
+            android:startColor="#55000000"
+            android:endColor="#00000000" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml
index c0252fa..26d2632 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml
@@ -14,15 +14,14 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:width="18dp"
+        android:width="9.0dp"
         android:height="18dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="12.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M4.300000,11.000000L2.700000,11.000000L2.700000,4.400000L1.000000,5.100000L1.000000,3.700000l3.100000,-1.300000l0.200000,0.000000L4.300000,11.000000z"/>
+        android:pathData="M3.500000,11.000000L1.800000,11.000000L1.800000,4.400000L0.200000,5.100000L0.200000,3.700000l3.100000,-1.300000l0.200000,0.000000L3.500000,11.000000z"/>
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M9.500000,5.500000l1.200000,-3.000000l1.900000,0.000000l-2.100000,4.200000l2.200000,4.300000l-1.900000,0.000000L9.500000,7.900000L8.300000,11.000000L6.300000,11.000000l2.100000,-4.300000L6.400000,2.500000l1.900000,0.000000L9.500000,5.500000z"/>
+        android:pathData="M8.600000,5.500000l1.200000,-3.000000l1.900000,0.000000L9.700000,6.700000l2.200000,4.300000L9.900000,11.000000L8.700000,7.900000L7.400000,11.000000L5.500000,11.000000l2.100000,-4.300000L5.600000,2.500000l1.900000,0.000000L8.600000,5.500000z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml
index 9a6a032..5aaf93b 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml
@@ -14,15 +14,14 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:width="18dp"
+        android:width="9.75dp"
         android:height="18dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="13.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M2.600000,6.000000l0.800000,0.000000c0.300000,0.000000 0.500000,-0.100000 0.700000,-0.300000s0.200000,-0.500000 0.200000,-0.900000c0.000000,-0.300000 -0.100000,-0.600000 -0.200000,-0.800000S3.700000,3.700000 3.500000,3.700000C3.200000,3.700000 3.000000,3.800000 2.900000,4.000000S2.600000,4.400000 2.600000,4.700000L1.000000,4.700000C1.000000,4.000000 1.200000,3.400000 1.700000,3.000000s1.000000,-0.600000 1.700000,-0.600000c0.800000,0.000000 1.400000,0.200000 1.900000,0.600000S6.000000,4.000000 6.000000,4.800000c0.000000,0.400000 -0.100000,0.700000 -0.300000,1.100000S5.200000,6.500000 4.800000,6.600000c0.400000,0.200000 0.700000,0.400000 0.900000,0.800000s0.300000,0.700000 0.300000,1.200000c0.000000,0.800000 -0.200000,1.400000 -0.700000,1.800000s-1.100000,0.700000 -1.900000,0.700000c-0.700000,0.000000 -1.300000,-0.200000 -1.800000,-0.600000s-0.700000,-1.000000 -0.700000,-1.800000l1.700000,0.000000c0.000000,0.300000 0.100000,0.600000 0.300000,0.800000s0.400000,0.300000 0.600000,0.300000c0.300000,0.000000 0.500000,-0.100000 0.700000,-0.300000S4.400000,9.000000 4.400000,8.600000c0.000000,-0.500000 -0.100000,-0.800000 -0.300000,-1.000000S3.700000,7.300000 3.400000,7.300000L2.600000,7.300000L2.600000,6.000000z"/>
+        android:pathData="M2.000000,6.000000l0.800000,0.000000c0.300000,0.000000 0.500000,-0.100000 0.700000,-0.300000s0.200000,-0.500000 0.200000,-0.900000c0.000000,-0.300000 -0.100000,-0.600000 -0.200000,-0.800000S3.200000,3.700000 2.900000,3.700000C2.700000,3.700000 2.500000,3.800000 2.300000,4.000000S2.100000,4.400000 2.100000,4.700000L0.500000,4.700000C0.500000,4.000000 0.700000,3.400000 1.100000,3.000000s1.000000,-0.600000 1.700000,-0.600000c0.800000,0.000000 1.400000,0.200000 1.900000,0.600000s0.700000,1.000000 0.700000,1.800000c0.000000,0.400000 -0.100000,0.700000 -0.300000,1.100000S4.600000,6.500000 4.300000,6.600000C4.700000,6.800000 5.000000,7.100000 5.200000,7.400000s0.300000,0.700000 0.300000,1.200000c0.000000,0.800000 -0.200000,1.400000 -0.700000,1.800000s-1.100000,0.700000 -1.900000,0.700000c-0.700000,0.000000 -1.300000,-0.200000 -1.800000,-0.600000s-0.700000,-1.000000 -0.700000,-1.800000L2.000000,8.700000C2.000000,9.000000 2.100000,9.300000 2.300000,9.500000s0.400000,0.300000 0.600000,0.300000c0.300000,0.000000 0.500000,-0.100000 0.700000,-0.300000S3.900000,9.000000 3.900000,8.600000c0.000000,-0.500000 -0.100000,-0.800000 -0.300000,-1.000000S3.200000,7.300000 2.800000,7.300000L2.000000,7.300000L2.000000,6.000000z"/>
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M13.100000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S7.300000,9.000000 7.300000,7.900000L7.300000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000s1.200000,-0.800000 2.100000,-0.800000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000S13.000000,4.200000 13.000000,5.100000l-1.600000,0.000000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000s-0.500000,-0.300000 -0.900000,-0.300000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S8.900000,5.000000 8.900000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L11.299999,7.800000l-1.300000,0.000000L9.999999,6.600000l2.900000,0.000000L12.900000,9.900000z"/>
+        android:pathData="M12.500000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S6.700000,9.000000 6.700000,7.900000L6.700000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000s1.200000,-0.800000 2.100000,-0.800000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000l-1.600000,0.000000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000s-0.500000,-0.300000 -0.900000,-0.300000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S8.400000,5.000000 8.400000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L10.799999,7.800000L9.600000,7.800000L9.600000,6.600000l2.900000,0.000000L12.500000,9.900000z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml
index 44f8cb1..b7d84f0 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml
@@ -14,15 +14,14 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:width="18dp"
+        android:width="9.0dp"
         android:height="18dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="12.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M5.700000,7.800000l0.700000,0.000000l0.000000,1.300000L5.700000,9.100000L5.700000,11.000000L4.000000,11.000000L4.000000,9.200000L1.200000,9.200000l-0.100000,-1.000000L4.000000,2.500000l1.700000,0.000000L5.700000,7.800000zM2.700000,7.800000L4.000000,7.800000l0.000000,-3.000000L4.000000,5.000000L2.700000,7.800000z"/>
+        android:pathData="M4.600000,7.800000l0.700000,0.000000l0.000000,1.300000L4.600000,9.100000L4.600000,11.000000L3.000000,11.000000L3.000000,9.200000L0.100000,9.200000L0.000000,8.100000L3.000000,2.500000l1.700000,0.000000L4.700000,7.800000zM1.600000,7.800000L3.000000,7.800000l0.000000,-3.000000L2.900000,5.000000L1.600000,7.800000z"/>
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M13.000000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S7.200000,9.000000 7.200000,7.900000L7.200000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000s1.200000,-0.800000 2.100000,-0.800000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000l-1.600000,0.000000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000s-0.500000,-0.300000 -0.900000,-0.300000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S8.800000,5.000000 8.800000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L11.200000,7.800000l-1.300000,0.000000L9.900000,6.600000L13.000000,6.600000L13.000000,9.900000z"/>
+        android:pathData="M11.900000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S6.100000,9.000000 6.100000,7.900000L6.100000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000S8.100000,2.400000 9.000000,2.400000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000l-1.600000,0.000000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000S9.500000,3.700000 9.000000,3.700000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S7.700000,5.000000 7.700000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L10.099999,7.800000L9.000000,7.800000L9.000000,6.600000l2.900000,0.000000L11.900000,9.900000z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml
index e9014ee..7111457 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml
@@ -14,12 +14,11 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:width="18dp"
+        android:width="3.75dp"
         android:height="18dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="5.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M5.900000,7.300000L3.100000,7.300000l0.000000,2.400000l3.300000,0.000000L6.400000,11.000000L1.400000,11.000000L1.400000,2.500000l4.900000,0.000000l0.000000,1.300000L3.100000,3.800000l0.000000,2.100000l2.800000,0.000000L5.900000,7.300000z"/>
+        android:pathData="M4.400000,7.300000L1.700000,7.300000l0.000000,2.400000l3.300000,0.000000L5.000000,11.000000L0.000000,11.000000L0.000000,2.500000l4.900000,0.000000l0.000000,1.300000L1.700000,3.800000l0.000000,2.100000l2.800000,0.000000L4.500000,7.300000z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml
index fcda0ad..97962b2 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml
@@ -14,12 +14,11 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:width="18dp"
+        android:width="5.25dp"
         android:height="18dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="7.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M7.500000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S1.700000,9.000000 1.700000,7.900000L1.700000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000s1.200000,-0.800000 2.100000,-0.800000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000L5.700000,5.200000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000S5.000000,3.700000 4.600000,3.700000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S3.300000,5.000000 3.300000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L5.700000,7.800000L4.500000,7.800000L4.500000,6.600000l2.900000,0.000000L7.400000,9.900000z"/>
+        android:pathData="M6.500000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S0.700000,9.000000 0.700000,7.900000L0.700000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000s1.200000,-0.800000 2.100000,-0.800000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000L4.700000,5.200000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000S4.000000,3.700000 3.600000,3.700000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S2.300000,5.000000 2.300000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L4.700000,7.800000L3.500000,7.800000L3.500000,6.600000l2.900000,0.000000L6.400000,9.900000z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml
index b5e9695..4859c14 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml
@@ -14,12 +14,11 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:width="18dp"
+        android:width="4.5dp"
         android:height="18dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="6.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M7.700000,11.000000L6.000000,11.000000L6.000000,7.500000L3.400000,7.500000L3.400000,11.000000L1.700000,11.000000L1.700000,2.500000l1.700000,0.000000l0.000000,3.700000L6.000000,6.200000L6.000000,2.500000l1.600000,0.000000L7.600000,11.000000z"/>
+        android:pathData="M6.000000,11.000000L4.400000,11.000000L4.400000,7.500000L1.700000,7.500000L1.700000,11.000000L0.000000,11.000000L0.000000,2.500000l1.700000,0.000000l0.000000,3.700000l2.700000,0.000000L4.400000,2.500000L6.000000,2.500000L6.000000,11.000000z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml
index a0cbe5f..d6446db 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml
@@ -14,10 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:width="18dp"
+        android:width="9.75dp"
         android:height="18dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="13.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_roam.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_roam.xml
index 4a542f9..7f7d5fc 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_roam.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_roam.xml
@@ -14,12 +14,11 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:width="18dp"
+        android:width="4.5dp"
         android:height="18dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="6.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M4.100000,7.900000l-1.000000,0.000000L3.100000,11.000000L1.400000,11.000000L1.400000,2.500000l2.700000,0.000000c0.900000,0.000000 1.500000,0.200000 2.000000,0.700000s0.700000,1.100000 0.700000,1.900000c0.000000,0.600000 -0.100000,1.100000 -0.300000,1.500000S6.000000,7.200000 5.600000,7.400000l1.500000,3.500000L7.100000,11.000000L5.400000,11.000000L4.100000,7.900000zM3.100000,6.500000l1.100000,0.000000c0.400000,0.000000 0.600000,-0.100000 0.800000,-0.400000s0.300000,-0.600000 0.300000,-1.000000c0.000000,-0.400000 -0.100000,-0.800000 -0.300000,-1.000000S4.600000,3.800000 4.200000,3.800000L3.100000,3.800000L3.100000,6.500000z"/>
+        android:pathData="M2.800000,7.900000l-1.000000,0.000000L1.800000,11.000000L0.200000,11.000000L0.200000,2.500000l2.700000,0.000000c0.900000,0.000000 1.500000,0.200000 2.000000,0.700000s0.700000,1.100000 0.700000,1.900000c0.000000,0.600000 -0.100000,1.100000 -0.300000,1.500000S4.800000,7.200000 4.400000,7.400000l1.500000,3.500000L5.900000,11.000000L4.100000,11.000000L2.800000,7.900000zM1.800000,6.500000l1.100000,0.000000c0.400000,0.000000 0.600000,-0.100000 0.800000,-0.400000S4.000000,5.600000 4.000000,5.200000c0.000000,-0.400000 -0.100000,-0.800000 -0.300000,-1.000000S3.300000,3.800000 2.900000,3.800000L1.800000,3.800000L1.800000,6.500000z"/>
 </vector>
diff --git a/packages/SystemUI/res/layout-land/status_bar_search_panel.xml b/packages/SystemUI/res/layout-land/status_bar_search_panel.xml
deleted file mode 100644
index ddffd6e..0000000
--- a/packages/SystemUI/res/layout-land/status_bar_search_panel.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* apps/common/assets/default/default/skins/StatusBar.xml
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<com.android.systemui.SearchPanelView
-    xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/search_panel_container"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    android:paddingBottom="0dip">
-
-    <RelativeLayout
-        android:id="@+id/search_bg_protect"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginBottom="0dip">
-
-        <RelativeLayout
-            android:id="@+id/search_panel_container"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_alignParentEnd="true">
-
-            <com.android.internal.widget.multiwaveview.GlowPadView
-                android:id="@+id/glow_pad_view"
-                android:orientation="vertical"
-                android:layout_width="@dimen/navbar_search_panel_height"
-                android:layout_height="match_parent"
-                android:layout_alignParentBottom="true"
-                android:gravity="start"
-
-                prvandroid:targetDrawables="@array/navbar_search_targets"
-                prvandroid:targetDescriptions="@array/navbar_search_target_descriptions"
-                prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
-                prvandroid:outerRingDrawable="@drawable/navbar_search_outerring"
-                prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
-                prvandroid:innerRadius="@dimen/glowpadview_inner_radius"
-                prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
-                prvandroid:feedbackCount="0"
-                prvandroid:vibrationDuration="@integer/config_vibration_duration"
-                prvandroid:alwaysTrackFinger="true"
-                prvandroid:glowRadius="@dimen/glowpadview_glow_radius"
-                prvandroid:pointDrawable="@drawable/ic_lockscreen_glowdot"
-                />
-
-        </RelativeLayout>
-
-    </RelativeLayout>
-
-</com.android.systemui.SearchPanelView>
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml
deleted file mode 100644
index 08f61bb..0000000
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* apps/common/assets/default/default/skins/StatusBar.xml
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<com.android.systemui.SearchPanelView
-    xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/search_panel_container"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent">
-
-    <com.android.internal.widget.multiwaveview.GlowPadView
-        android:id="@+id/glow_pad_view"
-        android:layout_width="wrap_content"
-        android:layout_height="@dimen/navbar_search_panel_height"
-        android:layout_gravity="center_horizontal|bottom"
-        android:gravity="center_horizontal|top"
-
-        prvandroid:targetDrawables="@array/navbar_search_targets"
-        prvandroid:targetDescriptions="@array/navbar_search_target_descriptions"
-        prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
-        prvandroid:outerRingDrawable="@drawable/navbar_search_outerring"
-        prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
-        prvandroid:innerRadius="@dimen/glowpadview_inner_radius"
-        prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
-        prvandroid:feedbackCount="0"
-        prvandroid:vibrationDuration="@integer/config_vibration_duration"
-        prvandroid:alwaysTrackFinger="true"
-        prvandroid:glowRadius="@dimen/glowpadview_glow_radius"
-        prvandroid:pointDrawable="@drawable/ic_lockscreen_glowdot"/>
-
-</com.android.systemui.SearchPanelView>
diff --git a/packages/SystemUI/res/layout/heads_up.xml b/packages/SystemUI/res/layout/heads_up.xml
index 0e2b6d6..650ee5d 100644
--- a/packages/SystemUI/res/layout/heads_up.xml
+++ b/packages/SystemUI/res/layout/heads_up.xml
@@ -14,6 +14,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
+<!-- extends FrameLayout -->
 <com.android.systemui.statusbar.policy.HeadsUpNotificationView
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_height="match_parent"
@@ -21,11 +22,12 @@
         android:background="@drawable/heads_up_scrim">
 
         <FrameLayout
+                android:layout_width="@dimen/notification_panel_width"
                 android:layout_height="wrap_content"
+                android:layout_gravity="@integer/notification_panel_layout_gravity"
                 android:paddingStart="@dimen/notification_side_padding"
                 android:paddingEnd="@dimen/notification_side_padding"
                 android:elevation="8dp"
-                android:id="@+id/content_holder"
-                style="@style/NotificationsQuickSettings" />
+                android:id="@+id/content_holder" />
 
 </com.android.systemui.statusbar.policy.HeadsUpNotificationView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index f831570..fc6e9ae 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -41,8 +41,8 @@
 
     <com.android.systemui.statusbar.KeyguardAffordanceView
         android:id="@+id/camera_button"
-        android:layout_height="64dp"
-        android:layout_width="64dp"
+        android:layout_height="@dimen/keyguard_affordance_height"
+        android:layout_width="@dimen/keyguard_affordance_width"
         android:layout_gravity="bottom|end"
         android:tint="#ffffffff"
         android:src="@drawable/ic_camera_alt_24dp"
@@ -51,8 +51,8 @@
 
     <com.android.systemui.statusbar.KeyguardAffordanceView
         android:id="@+id/phone_button"
-        android:layout_height="64dp"
-        android:layout_width="64dp"
+        android:layout_height="@dimen/keyguard_affordance_height"
+        android:layout_width="@dimen/keyguard_affordance_width"
         android:layout_gravity="bottom|start"
         android:tint="#ffffffff"
         android:src="@drawable/ic_phone_24dp"
@@ -61,8 +61,8 @@
 
     <com.android.systemui.statusbar.KeyguardAffordanceView
         android:id="@+id/lock_icon"
-        android:layout_width="64dp"
-        android:layout_height="64dp"
+        android:layout_width="@dimen/keyguard_affordance_width"
+        android:layout_height="@dimen/keyguard_affordance_height"
         android:layout_gravity="bottom|center_horizontal"
         android:src="@drawable/ic_lock_24dp"
         android:scaleType="center"
diff --git a/packages/SystemUI/res/layout/qs_detail.xml b/packages/SystemUI/res/layout/qs_detail.xml
index ca46437..c6a7368 100644
--- a/packages/SystemUI/res/layout/qs_detail.xml
+++ b/packages/SystemUI/res/layout/qs_detail.xml
@@ -17,7 +17,7 @@
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="@color/system_primary_color"
+    android:background="@drawable/qs_detail_background"
     android:padding="16dp" >
 
     <TextView
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index 087bf07..c76d442 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -19,6 +19,8 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:background="@drawable/qs_background_primary"
+        android:paddingTop="8dp"
+        android:paddingBottom="8dp"
         android:elevation="2dp">
 
     <com.android.systemui.qs.QSPanel
diff --git a/packages/SystemUI/res/layout/quick_settings_footer.xml b/packages/SystemUI/res/layout/quick_settings_footer.xml
new file mode 100644
index 0000000..53baf74
--- /dev/null
+++ b/packages/SystemUI/res/layout/quick_settings_footer.xml
@@ -0,0 +1,42 @@
+<?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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:clickable="true"
+    android:paddingBottom="@dimen/qs_tile_padding_top"
+    android:paddingTop="@dimen/qs_tile_padding_top" >
+
+    <TextView
+        android:id="@+id/footer_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:textSize="@dimen/qs_tile_text_size" />
+
+    <ImageView
+        android:id="@+id/footer_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerVertical="true"
+        android:layout_marginEnd="8dp"
+        android:layout_toStartOf="@id/footer_text"
+        android:contentDescription="@null"
+        android:src="@drawable/ic_qs_vpn"
+        android:visibility="invisible" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 53a832a..fc2dc02 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -55,7 +55,9 @@
         android:visibility="invisible" />
 
     <com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer
-        style="@style/NotificationsQuickSettings"
+        android:layout_width="@dimen/notification_panel_width"
+        android:layout_height="match_parent"
+        android:layout_gravity="@integer/notification_panel_layout_gravity"
         android:id="@+id/notification_container_parent"
         android:clipToPadding="false"
         android:clipChildren="false">
@@ -115,4 +117,12 @@
         layout="@layout/keyguard_bottom_area"
         android:visibility="gone" />
 
+    <com.android.systemui.statusbar.AlphaOptimizedView
+        android:id="@+id/qs_navbar_scrim"
+        android:layout_height="96dp"
+        android:layout_width="match_parent"
+        android:layout_gravity="bottom"
+        android:visibility="invisible"
+        android:background="@drawable/qs_navbar_scrim" />
+
 </com.android.systemui.statusbar.phone.NotificationPanelView><!-- end of sliding panel -->
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index 1afde69..688a88c 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -20,8 +20,9 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
     android:id="@+id/header"
-    style="@style/StatusBarHeader"
+    android:layout_width="@dimen/notification_panel_width"
     android:layout_height="@dimen/status_bar_header_height"
+    android:layout_gravity="@integer/notification_panel_layout_gravity"
     android:paddingStart="@dimen/notification_side_padding"
     android:paddingEnd="@dimen/notification_side_padding"
     android:baselineAligned="false"
diff --git a/packages/SystemUI/res/layout/status_bar_no_notifications.xml b/packages/SystemUI/res/layout/status_bar_no_notifications.xml
new file mode 100644
index 0000000..dd501d4
--- /dev/null
+++ b/packages/SystemUI/res/layout/status_bar_no_notifications.xml
@@ -0,0 +1,33 @@
+<!--
+  ~ 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
+  -->
+
+<!-- Extends Framelayout -->
+<com.android.systemui.statusbar.EmptyShadeView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        >
+    <TextView
+            android:id="@+id/no_notifications"
+            android:layout_width="match_parent"
+            android:layout_height="64dp"
+            android:paddingTop="12dp"
+            android:gravity="top|center_horizontal"
+            android:textColor="#ffffff"
+            android:textSize="20sp"
+            android:text="@string/empty_shade_text"/>
+</com.android.systemui.statusbar.EmptyShadeView>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml b/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
index 515270a..f506adc 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
@@ -21,20 +21,11 @@
         android:layout_height="wrap_content"
         android:visibility="gone"
         >
-    <Button
+    <ImageButton
             android:id="@+id/dismiss_text"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:minHeight="0dp"
-            android:textColor="#ffffffff"
-            android:text="@string/clear_all_notifications_text"
-            android:textSize="18sp"
-            android:textAllCaps="true"
-            android:paddingTop="@dimen/clear_all_padding_top"
-            android:paddingEnd="8dp"
-            android:layout_gravity="end|center_vertical"
-            android:drawableEnd="@drawable/ic_clear_all"
-            android:drawablePadding="4dp"
-            android:fontFamily="sans-serif-light"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
+            android:layout_gravity="end"
+            android:src="@drawable/ic_dismiss_all"
             android:background="@drawable/ripple_drawable" />
 </com.android.systemui.statusbar.DismissView>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml b/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml
index f0f50e1..eff3758 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml
@@ -30,25 +30,39 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         />
-    <TextView
-        android:id="@+id/more_text"
-        android:layout_width="32dp"
-        android:layout_height="32dp"
-        android:layout_marginStart="20dp"
-        android:layout_gravity="center_vertical"
-        android:background="@drawable/keyguard_overflow_number_background"
-        android:gravity="center"
-        android:textColor="#ff686868"
-        android:textStyle="bold"
-        android:textSize="14dp"
-        />
-    <com.android.systemui.statusbar.NotificationOverflowIconsView
-        android:id="@+id/overflow_icons_view"
-        android:layout_gravity="center_vertical"
-        android:layout_marginStart="68dp"
-        android:layout_width="120dp"
-        android:layout_height="wrap_content"
-        />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <TextView
+            android:id="@+id/more_text"
+            android:layout_width="32dp"
+            android:layout_height="32dp"
+            android:layout_marginStart="20dp"
+            android:layout_marginEnd="16dp"
+            android:layout_gravity="center_vertical"
+            android:background="@drawable/keyguard_overflow_number_background"
+            android:gravity="center"
+            android:textColor="#ff686868"
+            android:textStyle="bold"
+            android:textSize="14dp"
+            />
+        <com.android.systemui.statusbar.StatusBarIconView
+            android:id="@+id/more_icon_overflow"
+            android:layout_width="@dimen/status_bar_icon_size"
+            android:layout_height="match_parent"
+            android:src="@drawable/stat_notify_more"
+            android:tint="@color/keyguard_overflow_content_color"
+            android:visibility="gone"
+            />
+        <com.android.systemui.statusbar.NotificationOverflowIconsView
+            android:id="@+id/overflow_icons_view"
+            android:layout_gravity="center_vertical"
+            android:layout_marginEnd="8dp"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            />
+    </LinearLayout>
 
     <com.android.systemui.statusbar.NotificationScrimView
         android:id="@+id/scrim_view"
diff --git a/packages/SystemUI/res/layout/status_bar_search_panel.xml b/packages/SystemUI/res/layout/status_bar_search_panel.xml
index c01db7c..f025abd 100644
--- a/packages/SystemUI/res/layout/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout/status_bar_search_panel.xml
@@ -18,50 +18,29 @@
 */
 -->
 
+<!-- Extends FrameLayout -->
 <com.android.systemui.SearchPanelView
-    xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/search_panel_container"
     android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    android:paddingBottom="0dip">
+    android:layout_width="match_parent">
 
-    <RelativeLayout
-        android:id="@+id/search_bg_protect"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginBottom="0dip">
+    <com.android.systemui.statusbar.AlphaOptimizedView
+        style="@style/SearchPanelScrim"
+        android:id="@+id/search_panel_scrim"
+        android:background="@drawable/search_panel_scrim" />
 
-        <RelativeLayout
-            android:id="@+id/search_panel_container"
-            android:layout_width="match_parent"
+    <FrameLayout
+        style="@style/SearchPanelCard"
+        android:id="@+id/search_panel_card"
+        android:background="@drawable/search_panel_card_bg"
+        android:elevation="12dp">
+
+        <ImageView
+            style="@style/SearchPanelLogo"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_alignParentBottom="true">
-
-            <com.android.internal.widget.multiwaveview.GlowPadView
-                android:id="@+id/glow_pad_view"
-                android:orientation="horizontal"
-                android:layout_width="match_parent"
-                android:layout_height="@dimen/navbar_search_panel_height"
-                android:layout_alignParentBottom="true"
-                android:gravity="top"
-
-                prvandroid:targetDrawables="@array/navbar_search_targets"
-                prvandroid:targetDescriptions="@array/navbar_search_target_descriptions"
-                prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
-                prvandroid:outerRingDrawable="@drawable/navbar_search_outerring"
-                prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
-                prvandroid:innerRadius="@dimen/glowpadview_inner_radius"
-                prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
-                prvandroid:feedbackCount="0"
-                prvandroid:vibrationDuration="@integer/config_vibration_duration"
-                prvandroid:alwaysTrackFinger="true"
-                prvandroid:glowRadius="@dimen/glowpadview_glow_radius"
-                prvandroid:pointDrawable="@drawable/ic_lockscreen_glowdot"
-               />
-
-        </RelativeLayout>
-
-    </RelativeLayout>
+            android:id="@+id/search_logo" />
+    </FrameLayout>
 
 </com.android.systemui.SearchPanelView>
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 112f3a9..3765fe8 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -15,8 +15,10 @@
      limitations under the License.
 -->
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="@dimen/volume_panel_width"
+    android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:layout_marginLeft="@dimen/notification_side_padding"
+    android:layout_marginRight="@dimen/notification_side_padding"
     android:background="@drawable/qs_background_primary"
     android:translationZ="@dimen/volume_panel_z"
     android:layout_marginBottom="@dimen/volume_panel_z">
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 77a8024..4c43069 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Laai met USB word nie gesteun nie."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Gebruik slegs die laaier wat verskaf is."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Instellings"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Aktiveer batteryspaarder?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Begin"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Aktiveer batteryspaarder"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Om die batteryleeftyd te help verbeter, sal Batteryspaarder jou toestel se werkverrigting verminder.\n\nBatteryspaarder sal gedeaktiveer word wanneer jou toestel ingeprop word."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Instellings"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Vliegtuigmodus"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d uur lank"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Batteryspaarder is aan"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Toestel se werkverrigting is verminder."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Maak batteryspaarder se instellings oop"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Inhoud versteek"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sal alles begin vasvang wat op jou skerm gewys word."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Vee alles uit"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Begin nou"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Geen kennisgewings nie"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index d8959a5..faf8284 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"የUSB ኃይል መሙላት አይደገፍም።"</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"የቀረበውን ኃይል መሙያ ብቻ ይጠቀሙ።"</string>
     <string name="battery_low_why" msgid="4553600287639198111">"ቅንብሮች"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"የባህሪ ኃይል ቆጣቢው ይጀመር?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"ጀምር"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"የባህሪ ኃይል ቆጣቢው ይጀመር"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"የባትሪ በህይወት የመቆየት ጊዜን ለማሻሻል እንዲያግዝ፣ የባትሪ ኃይል ቆጣቢው የመሳሪያዎን የመስራት አቅም ይቀንሰዋል።\n\nየባትሪ ኃይል ቆጣቢው መሳሪያዎ የተሰካ ሲሆን ይሰናከላል።"</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"ቅንብሮች"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"የአውሮፕላን ሁነታ"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"ለ%d ሰዓቶች"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"የባትሪ ኃይል ቆጣቢ በርቷል"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"የመሳሪያው የአሰራር ብቃት ተቀንሷል።"</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"የባትሪ ኃይል ቆጣቢ ቅንብሮች"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"ይዘቶች ተደብቀዋል"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> በማያ ገጽዎ ላይ የታየውን ነገር በሙሉ ማንሳት ይጀምራል።"</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"ሁሉንም አጽዳ"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"አሁን ጀምር"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"ምንም ማሳወቂያ የለም"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 93e3cbe..66f51d7 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"‏لا يمكن إجراء الشحن عبر USB."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"لا تستخدم سوى الشاحن المزوّد."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"الإعدادات"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"هل تريد بدء وضع توفير الطاقة؟"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"بدء"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"بدء وضع توفير الطاقة"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"للمساعدة في إطالة عمر البطارية، فإن وضع توفير الطاقة سيقلل من أداء جهازك.\n\nسيتم تعطيل وضع توفير الطاقة عند توصيل جهازك بالشاحن."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"الإعدادات"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"وضع الطائرة"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"‏لمدة %d من الساعات"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"وضع توفير الطاقة قيد التشغيل"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"تم تقليل أداء الجهاز."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"فتح إعدادات وضع توفير الطاقة"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"المحتويات مخفية"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> سيبدأ التقاط كل شيء يتم عرضه على الشاشة."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"محو الكل"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"البدء الآن"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"ليس هناك أي اشعارات"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 0e7d18c..9382e02 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Зареждането през USB не се поддържа."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Използвайте само предоставеното зарядно устройство."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Настройки"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Да се стартира ли режимът за запазване на батерията?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Стартиране"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Стартиране на режима за запазване на батерията"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"С цел удължаване на живота на батерията режимът за запазването й ще намали ефективността на устройството ви.\n\nКогато то е включено в захранването, режимът ще се деактивира."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Настройки"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Самолетен режим"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"За %d часа"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Режимът за запазване на батерията е включен"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Ефективността на устройството е намалена."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Отваряне на настройките за режима за запазване на батерията"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Скрито съдържание"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ще започне да заснема всичко, което се показва на екрана ви."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Изчистване на всички"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Стартиране сега"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Няма известия"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index bd18195..4015eab 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB চার্জিং সমর্থিত নয়।"</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"শুধুমাত্র সরবরাহকৃত চার্জার ব্যবহার করুন।"</string>
     <string name="battery_low_why" msgid="4553600287639198111">"সেটিংস"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"ব্যাটারি সেভার শুরু করুন?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"আরম্ভ"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"ব্যাটারি সেভার শুরু করুন"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"ব্যাটারি জীবন উন্নত করার ক্ষেত্রে সাহায্যের জন্য, ব্যাটারি সেভার আপনার ডিভাইসের কর্মক্ষমতা হ্রাস করবে।\n \n আপনার ডিভাইস প্লাগ ইন করা হলে ব্যাটারি সেভার অক্ষম হবে।"</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"সেটিংস"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"বিমান মোড"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d ঘন্টার জন্য"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"ব্যাটারি সেভার চালু রয়েছে"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"ডিভাইসের কর্মক্ষমতা কমে যাবে।"</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"ব্যাটারি সেভার সেটিংস খুলুন"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"লুকানো বিষয়বস্তু"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> আপনার স্ক্রীনে দেখানো সব কিছু ক্যাপচার করা শুরু করবে।"</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"সবকিছু সাফ করুন"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"এখন শুরু করুন"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"কোনো বিজ্ঞপ্তি নেই"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index d1e28af..ee55940 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"La càrrega per USB no és compatible."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Fes servir només el carregador proporcionat amb el dispositiu."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Configuració"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Vols iniciar la funció Estalvi de bateria?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Inicia"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Inicia la funció Estalvi de bateria"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"La funció Estalvi de bateria reduirà el rendiment del dispositiu per tal d\'augmentar la durada de la bateria.\n\nAquesta funció es desactivarà quan el dispositiu estigui connectat."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Configuració"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Mode d\'avió"</string>
@@ -288,8 +290,10 @@
     <item quantity="other" msgid="5408537517529822157">"Durant %d hores"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"La funció Estalvi de bateria està activada."</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"S\'ha reduït el rendiment del dispositiu."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Obre la configuració de la funció Estalvi de bateria"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Contingut amagat"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> començarà a enregistrar tot el que es mostri a la pantalla."</string>
@@ -297,4 +301,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Esborra-ho tot"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Comença ara"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Cap notificació"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index efe8df5..5280acd 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Nabíjení přes USB není podporováno."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Používejte pouze nabíječku, která je součástí balení."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Nastavení"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Aktivovat režim Úspora baterie?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Spustit"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Aktivovat režim Úspora baterie"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"V režimu Úspora baterie se omezí výkon zařízení, aby se tak prodloužila výdrž baterie.\n\nRežim Úspora baterie se deaktivuje, když bude zařízení zapojeno do zásuvky."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Nastavení"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Režim V letadle"</string>
@@ -288,8 +290,10 @@
     <item quantity="other" msgid="5408537517529822157">"Na %d h"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Režim Úspora baterie je zapnutý."</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Výkon zařízení je snížen."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Otevřít nastavení režimu Úspora baterie"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g> %%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Skrytý obsah"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"Aplikace <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> začne zaznamenávat vše, co je zobrazeno na obrazovce."</string>
@@ -297,4 +301,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Smazat vše"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Spustit"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Žádná oznámení"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index aa09668..9d3416d 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB-opladning understøttes ikke."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Brug kun den oplader, der føler med."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Indstillinger"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Vil du starte Batteribesparende?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Startet"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Start Batteribesparende"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"For at hjælpe med at forbedre batteriets levetid, reducerer Batteribesparende enhedens ydeevne.\n\nBatteribesparende slukkes, når strømstikket er sat i."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Indstillinger"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Flytilstand"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"I %d timer"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Batteribesparende er slået til"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Enhedens ydeevne reduceres."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Åbn indstillinger for Batteribesparende"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g> %%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Indholdet er skjult"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vil begynde at optage alt, hvad der vises på din skærm."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Ryd alt"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Start nu"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ingen underretninger"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index f2382e8..6688c6a 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Laden per USB wird nicht unterstützt."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Verwenden Sie nur das im Lieferumfang enthaltene Ladegerät."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Einstellungen"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Energiesparmodus starten?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Starten"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Energiesparmodus starten"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Im Energiesparmodus wird zur Schonung des Akkus die Leistung des Geräts herabgesetzt.\n\nSobald Ihr Gerät an eine Stromquelle angeschlossen ist, wird der Energiesparmodus deaktiviert."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Einstellungen"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"WLAN"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Flugmodus"</string>
@@ -288,8 +290,10 @@
     <item quantity="other" msgid="5408537517529822157">"Für %d Stunden"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Energiesparmodus ist aktiviert"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Die Geräteleistung wurde herabgesetzt."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Einstellungen für den Energiesparmodus öffnen"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g> %%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Inhalte ausgeblendet"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> nimmt alle auf Ihrem Bildschirm angezeigten Aktivitäten auf."</string>
@@ -297,4 +301,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Alle löschen"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Jetzt starten"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Keine Benachrichtigungen"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index dcc6638..dee321b 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Δεν υποστηρίζεται η φόρτιση μέσω USB."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Χρήση μόνο του παρεχόμενου φορτιστή."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Ρυθμίσεις"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Έναρξη Εξοικονόμησης μπαταρίας;"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Έναρξη"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Έναρξη Εξοικονόμησης μπαταρίας"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Για να συμβάλει στη βελτίωση της διάρκειας ζωής της μπαταρίας, η Εξοικονόμηση μπαταρίας θα μειώσει την απόδοση της συσκευής σας.\n\nΗ Εξοικονόμηση μπαταρίας θα απενεργοποιηθεί όταν η συσκευή σας συνδεθεί για φόρτιση."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Ρυθμίσεις"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Λειτουργία πτήσης"</string>
@@ -288,8 +290,10 @@
     <item quantity="other" msgid="5408537517529822157">"Για %d ώρες"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Η Εξοικονόμηση μπαταρίας είναι ενεργή"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Η απόδοση της συσκευής μειώνεται."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Άνοιγμα ρυθμίσεων Εξοικονόμησης μπαταρίας"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Κρυφό περιεχόμενο"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"Θα ξεκινήσει η καταγραφή του περιεχομένου που εμφανίζεται στην οθόνη σας από την εφαρμογή <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>."</string>
@@ -297,4 +301,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Διαγραφή όλων"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Έναρξη τώρα"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Δεν υπάρχουν ειδοποιήσεις"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index b15791a..3fc88e9 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -39,10 +39,9 @@
     <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="5987726159603849352">"Start battery saver?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Start"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Start battery saver"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"To help improve battery life, Battery saver will reduce your device’s performance.\n\nBattery saver will be disabled when your device is plugged in."</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>
@@ -286,8 +285,8 @@
     <item quantity="other" msgid="5408537517529822157">"For %d hours"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Battery saver is on"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Device performance is reduced."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Open battery saver settings"</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="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</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>
@@ -295,4 +294,15 @@
     <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="vpn_footer" msgid="2388611096129106812">"Network may be monitored"</string>
+    <string name="monitoring_title_device_owned" msgid="7121079311903859610">"Device monitoring"</string>
+    <string name="monitoring_title" msgid="169206259253048106">"Network monitoring"</string>
+    <string name="open_app" msgid="4011771120339160755">"Open app"</string>
+    <string name="disconnect_vpn" msgid="1324915059568548655">"Disconnect VPN"</string>
+    <string name="monitoring_description_device_owned" msgid="7801926679066533391">"This device is managed by:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nYour administrator can monitor your network activity, including emails, apps and secure websites.\n\nFor more information, contact your administrator."</string>
+    <string name="monitoring_description_vpn" msgid="93140751707065515">"You gave \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" permission to set up a VPN connection.\n\nThis app can monitor your network activity, including emails, apps and secure websites."</string>
+    <string name="monitoring_description_legacy_vpn" msgid="5397847778080663075">"You\'re connected to a VPN (\"<xliff:g id="APPLICATION">%1$s</xliff:g>\").\n\nYour VPN service provider can monitor your 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>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index b15791a..3fc88e9 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -39,10 +39,9 @@
     <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="5987726159603849352">"Start battery saver?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Start"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Start battery saver"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"To help improve battery life, Battery saver will reduce your device’s performance.\n\nBattery saver will be disabled when your device is plugged in."</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>
@@ -286,8 +285,8 @@
     <item quantity="other" msgid="5408537517529822157">"For %d hours"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Battery saver is on"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Device performance is reduced."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Open battery saver settings"</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="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</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>
@@ -295,4 +294,15 @@
     <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="vpn_footer" msgid="2388611096129106812">"Network may be monitored"</string>
+    <string name="monitoring_title_device_owned" msgid="7121079311903859610">"Device monitoring"</string>
+    <string name="monitoring_title" msgid="169206259253048106">"Network monitoring"</string>
+    <string name="open_app" msgid="4011771120339160755">"Open app"</string>
+    <string name="disconnect_vpn" msgid="1324915059568548655">"Disconnect VPN"</string>
+    <string name="monitoring_description_device_owned" msgid="7801926679066533391">"This device is managed by:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nYour administrator can monitor your network activity, including emails, apps and secure websites.\n\nFor more information, contact your administrator."</string>
+    <string name="monitoring_description_vpn" msgid="93140751707065515">"You gave \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" permission to set up a VPN connection.\n\nThis app can monitor your network activity, including emails, apps and secure websites."</string>
+    <string name="monitoring_description_legacy_vpn" msgid="5397847778080663075">"You\'re connected to a VPN (\"<xliff:g id="APPLICATION">%1$s</xliff:g>\").\n\nYour VPN service provider can monitor your 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>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index f21472f..b9f7c8d 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"No se admite la carga por USB."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Usa solo el cargador suministrado."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Configuración"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"¿Quieres iniciar el ahorro de batería?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Iniciar"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Iniciar ahorro de batería"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Para ayudar a mejorar la duración de la batería, el ahorro de batería reducirá el rendimiento del dispositivo.\n\nEsta función se inhabilitará cuando el dispositivo esté conectado."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Configuración"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Modo avión"</string>
@@ -288,8 +290,10 @@
     <item quantity="other" msgid="5408537517529822157">"Durante %d horas"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Ahorro de batería activado"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Rendimiento del dispositivo reducido"</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Abrir configuración del ahorro de batería"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Contenidos ocultos"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> comenzará la captura de todo lo que se muestre en la pantalla."</string>
@@ -297,4 +301,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Borrar todo"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Comenzar ahora"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"No hay notificaciones"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index be9d2fb..2260d7d 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"No se admite la carga por USB."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Utiliza solo el cargador proporcionado."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Ajustes"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"¿Iniciar ahorro de batería?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Iniciar"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Iniciar ahorro de batería"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Para ayudar a mejorar la duración de la batería, la función de ahorro de energía reducirá el rendimiento del dispositivo.\n\nEsta función estará inhabilitada cuando el dispositivo esté enchufado."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Ajustes"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Modo avión"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"Durante %d horas"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Ahorro de batería activado"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Rendimiento del dispositivo reducido."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Abrir ajustes de la función de ahorro de batería"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Contenidos ocultos"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> empezará a capturar todo lo que aparezca en la pantalla."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Borrar todo"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Iniciar ahora"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ninguna notificación"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 36765c3..8c3ee90 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB-ga laadimist ei toetata."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Kasutage ainult kaasasolevat laadijat."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Seaded"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Kas käivitada akusäästja?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Käivita"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Käivita akusäästja"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Aku tööea parandamiseks vähendab akusäästja teie seadme jõudlust.\n\nKui seade ühendatakse toiteallikaga, keelatakse akusäästja."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Seaded"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"WiFi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Lennurežiim"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d tunniks"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Akusäästja on sisse lülitatud"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Seadme jõudlust on vähendatud."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Ava akusäästja seaded"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Sisu on peidetud"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> hakkab jäädvustama kõike, mida ekraanil kuvatakse."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Tühjenda kõik"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Alusta kohe"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Märguandeid pole"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index a0a7eac..4c67086 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Ez da USB bidez kargatzea onartzen."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Erabili jatorrizko kargagailua soilik."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Ezarpenak"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Bateria aurrezlea aktibatu nahi duzu?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Hasi"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Aktibatu bateria aurrezlea"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Bateria aurrezleak gailuaren funtzionamendua erregulatzen du, energiaren kontsumoa murriztuta bateriak gehiago iraun dezan.\n\nGailua kargagailura konektatzen duzunean Bateria aurrezlea desaktibatu egingo da."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Ezarpenak"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Hegaldi modua"</string>
@@ -286,13 +288,37 @@
     <item quantity="other" msgid="5408537517529822157">"%d orduz"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Bateria aurrezlea aktibatuta dago"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Gailuaren funtzioak murrizten dira, energia gutxiago kontsumi dezan."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Ireki bateria aurrezlearen ezarpenak"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"%% <xliff:g id="LEVEL">%d</xliff:g>"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Edukiak ezkutatuta daude"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aplikazioak pantailan bistaratzen den guztia grabatuko du."</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ez erakutsi berriro"</string>
-    <string name="clear_all_notifications_text" msgid="814192889771462828">"Garbitu guztia"</string>
+    <string name="clear_all_notifications_text" msgid="814192889771462828">"Garbitu guztiak"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Hasi"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ez dago jakinarazpenik"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 1037eea..9f39599 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"‏شارژ با USB پشتیبانی نمی‌شود."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"فقط از شارژر ارائه شده استفاده کنید."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"تنظیمات"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"ذخیره کننده باتری شروع شود؟"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"شروع"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"شروع ذخیره کننده باتری"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"ذخیره کننده باتری برای کمک به بهبود عمر باتری شما، عملکرد دستگاهتان را کاهش می‌دهد.\n\nهنگامی که دستگاه شما به برق وصل است، ذخیره کننده باتری خاموش می‌شود."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"تنظیمات"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"حالت هواپیما"</string>
@@ -241,7 +243,7 @@
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"هشدار <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="recents_empty_message" msgid="7883614615463619450">"هیچ برنامه جدیدی موجود نیست"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"اطلاعات برنامه"</string>
-    <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"قفل در برنامه"</string>
+    <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"قفل به برنامه"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"جستجو"</string>
     <string name="expanded_header_battery_charged" msgid="5945855970267657951">"شارژ کامل شد"</string>
     <string name="expanded_header_battery_charging" msgid="205623198487189724">"در حال شارژ شدن"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"‏برای %d ساعت"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"ذخیره کننده باتری روشن است."</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"عملکرد دستگاه کاهش یافته است."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"باز کردن تنظیمات ذخیره کننده باتری"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>٪٪"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"محتواها پنهان هستند"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> شروع به ضبط هر چیزی می‌کند که در صفحه‌نمایش شما نمایش داده می‌شود."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"پاک کردن همه موارد"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"اکنون شروع شود"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"اعلانی موجود نیست"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 139d12a..7bef3aa 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB-latausta ei tueta."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Käytä vain laitteen mukana toimitettua laturia."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Asetukset"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Käynnistetäänkö virransäästö?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Käynnistä"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Käynnistä virransäästö"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Virransäästötoiminto pidentää akun kestoa vähentämällä laitteen virrankulutusta.\n\nLaitteen kytkeminen virtalähteeseen poistaa virransäästön käytöstä."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Asetukset"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Lentokonetila"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d tunniksi"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Virransäästö on käytössä"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Laitteen virrankulutusta vähennetään."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Avaa virransäästöasetukset"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <!-- String.format failed for translation -->
     <!-- no translation found for battery_level_template (1609636980292580020) -->
     <skip />
@@ -297,4 +301,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Poista kaikki"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Aloita nyt"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ei ilmoituksia"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 970b133..cf0095b 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Le chargement par USB n\'est pas pris en charge."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Utilisez uniquement le chargeur fourni."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Paramètres"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Démarrer la fonction Économie d\'énergie?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Démarrer"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Démarrer la fonction Économie d\'énergie"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Pour vous aider à prolonger l\'autonomie de votre appareil, la fonction Économie d\'énergie réduit les performances de l\'appareil.\n\nElle se désactive lorsque l\'appareil est branché."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Paramètres"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Mode Avion"</string>
@@ -288,8 +290,10 @@
     <item quantity="other" msgid="5408537517529822157">"Pendant %d heures"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"La fonction Économie d\'énergie est activée"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Les performances de l\'appareil sont réduites."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Ouvrir les paramètres d\'économie d\'énergie"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g> %%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Contenus masqués"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> commencer à enregistrer tout ce qui s\'affiche sur votre écran."</string>
@@ -297,4 +301,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Tout effacer"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Commencer maintenant"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Aucune notification"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index c85749a..41f4df4 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Chargeur USB non compatible."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Veuillez n\'utiliser que le chargeur fourni."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Paramètres"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Démarrer l\'économiseur de batterie ?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Démarrer"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Démarrer l\'économiseur de batterie"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Pour vous aider à prolonger l\'autonomie de la batterie, les performances de l\'appareil sont réduites.\n\nL\'économiseur de batterie est désactivé lorsque l\'appareil est branché."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Paramètres"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Mode Avion"</string>
@@ -288,8 +290,10 @@
     <item quantity="other" msgid="5408537517529822157">"Pendant %d heures"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"L\'économiseur de batterie est activé"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Les performances de l\'appareil sont réduites."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Ouvrir les paramètres de l\'économiseur de batterie"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g> %%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Contenus masqués"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> va commencer à capturer tous les contenus affichés à l\'écran."</string>
@@ -297,4 +301,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Tout effacer"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Commencer"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Aucune notification"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index 500bb57..aedbd03 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Non se admite a carga mediante USB."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Utiliza soamente o cargador fornecido."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Configuración"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Iniciar aforrador de batería?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Iniciar"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Iniciar o aforrador de batería"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Para axudar a mellorar a duración da batería, o aforrador de batería reducirá o rendemento do dispositivo.\n\nO aforrador de batería desactivarase cando enchufes o dispositivo."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Configuración"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Modo avión"</string>
@@ -288,8 +290,10 @@
     <item quantity="other" msgid="5408537517529822157">"Durante %d horas"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"O aforrador de batería está activado"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Reduciuse o rendemento do dispositivo."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Abrir a configuración do aforrador de batería"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Contido oculto"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> comezará a capturar todo o que apareza na túa pantalla."</string>
@@ -297,4 +301,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Eliminar todas"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Iniciar agora"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Non hai notificacións"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index fa9622f..5a53ee9 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB चार्जिंग समर्थित नहीं है."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"केवल आपूर्ति किए गए चार्जर का उपयोग करें."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"सेटिंग"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"बैटरी सेवर प्रारंभ करें?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"प्रारंभ करें"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"बैटरी सेवर प्रारंभ करें"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"बैटरी का जीवनकाल बेहतर बनाने में सहायता के लिए, बैटरी सेवर आपके उपकरण के प्रदर्शन को कम कर देगा.\n\nआपका उपकरण प्लग किए जाने पर बैटरी सेवर अक्षम हो जाएगा."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"सेटिंग"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"वाई-फ़ाई"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"हवाई जहाज मोड"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d घंटे के लिए"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"बैटरी सेवर चालू है"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"उपकरण का प्रदर्शन कम हो गया है."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"बैटरी सेवर सेटिंग चालू करें"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"छिपी हुई सामग्री"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> आपके स्क्रीन पर प्रदर्शित प्रत्येक सामग्री को कैप्चर करना प्रारंभ कर देगी."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"सभी साफ करें"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"अब प्रारंभ करें"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"कोई सूचना नहीं"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 24bc8c9..43c9207 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Punjenje putem USB-a nije podržano."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Upotrebljavajte samo priloženi punjač."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Postavke"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Želite li pokrenuti štednju baterije?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Kreni"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Pokretanje štednje baterije"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Da bi baterija trajala dulje, Štednja baterije smanjit će intenzitet rada uređaja.\n\nŠtednja baterije onemogućit će se kada je uređaj priključen."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Postavke"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Način rada u zrakoplovu"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d h"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Štednja baterije je uključena"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Uređaj radi smanjenim intenzitetom."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Otvaranje postavki štednje baterije"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Sadržaj je skriven"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"Aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> počet će snimati sve što se prikazuje na zaslonu."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Izbriši sve"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Započni sad"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nema obavijesti"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index f537e8c..ed26b93 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Az USB-n keresztüli töltés nem támogatott."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Kizárólag a tartozékként kapott töltőt használja."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Beállítások"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Elindítja az Akkumulátorkímélő módot?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Indítás"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Akkumulátorkímélő mód indítása"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Az Akkumulátorkímélő mód csökkenti az eszköz teljesítményét, hogy növelje az akkumulátor üzemidejét.\n\nAz eszköz töltésekor az Akkumulátorkímélő üzemmód kikapcsol."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Beállítások"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Repülőgép üzemmód"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d órán át"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Akkumulátorkímélő mód bekapcsolva"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Az eszköz teljesítménye lecsökkentve."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Akkumulátorkímélő mód beállításainak megnyitása"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>. szint"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Tartalomjegyzék elrejtve"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"A(z) <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> alkalmazás rögzíteni fog mindent, ami megjelenik a képernyőn."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Az összes törlése"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Indítás most"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nincs értesítés"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index f4a44ff..80d1aa4 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB լիցքավորումը չի աջակցվում:"</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Օգտագործեք միայն մատակարարի տրամադրած լիցքավորիչը:"</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Կարգավորումներ"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Գործարկե՞լ մարտկոցի տնտեսումը:"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Մեկնարկել"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Գործարկել մարտկոցի տնտեսումը"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Մարտկոցի տնտեսումը կնվազեցնի ձեր սարքի կատարողականը՝ մարտկոցն ավելի երկար օգտագործելու համար:\n\nՄարտկոցի տնտեսումը կանջատվի, հենց սարքը միացնեք հոսանքի աղբյուրին:"</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Կարգավորումներ"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Ինքնաթիռային ռեժիմ"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d ժամ"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Մարտկոցի տնտեսումը միացված է"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Սարքի կատարողականը նվազեցված է:"</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Բացել մարտկոցի տնտեսման կարգավորումները"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Բովանդակությունը թաքցված է"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ծրագիրը կսկսի հավաքագրել այն ամենն ինչ ցուցադրվում է ձեր էկրանին:"</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Մաքրել բոլորը"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Մեկնարկել հիմա"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ծանուցումներ չկան"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 43cf75d..1e8d882 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Pengisian daya USB tidak didukung."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Hanya gunakan pengisi daya yang disediakan."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Setelan"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Mulai penghemat baterai?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Mulai"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Mulai penghemat baterai"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Untuk membantu meningkatkan masa pakai baterai, Penghemat baterai akan mengurangi kinerja perangkat Anda.\n\nPenghemat baterai akan dinonaktifkan saat perangkat dihubungkan dengan sumber daya."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Setelan"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Mode pesawat"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"Selama %d jam"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Penghemat baterai aktif"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Kinerja perangkat dikurangi."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Buka setelan penghemat baterai"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Konten tersembunyi"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> akan mulai menangkap apa saja yang ditampilkan pada layar Anda."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Hapus semua"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Mulai sekarang"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Tidak ada pemberitahuan"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index 329bbc6..153ece3 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Ekki er stuðningur við USB-hleðslu."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Notaðu eingöngu hleðslutækið sem fylgir með."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Stillingar"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Kveikja á rafhlöðusparnaði?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Kveikja"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Kveikja á rafhlöðusparnaði"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Til að lengja endingartíma rafhlöðunnar minnkar rafhlöðusparnaðareiginleikinn afköst tækisins.\n\nSlökkt er á sparnaðareiginleikanum þegar tækið er sett í samband."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Stillingar"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Flugstilling"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"Í %d klukkustundir"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Kveikt er á rafhlöðusparnaði"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Þetta dregur úr afköstum tækisins."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Opna stillingar rafhlöðusparnaðar"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Innihald falið"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> mun fanga allt sem birtist á skjánum."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Hreinsa allt"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Byrja núna"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Engar tilkynningar"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index b8d5f36..3828e23 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Ricarica tramite USB non supportata."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Utilizza solo il caricabatterie fornito in dotazione."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Impostazioni"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Avviare risparmio batteria?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Avvia"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Avvia risparmio batteria"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Per aumentare la durata della batteria, Risparmio batteria riduce le prestazioni del tuo dispositivo.\n\nRisparmio batteria si disattiva quando il dispositivo è collegato alla corrente."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Impostazioni"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Modalità aereo"</string>
@@ -288,8 +290,10 @@
     <item quantity="other" msgid="5408537517529822157">"Per %d ore"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Risparmio batteria attivo"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Le prestazioni del dispositivo sono ridotte."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Apri impostazioni risparmio batteria"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Contenuti nascosti"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> inizierà ad acquisire tutto ciò che è visualizzato sul tuo schermo."</string>
@@ -297,4 +301,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Cancella tutto"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Avvia adesso"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nessuna notifica"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index ff15af0..1f64088 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"‏טעינה בחיבור USB אינה נתמכת."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"השתמש רק במטען שסופק."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"הגדרות"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"האם להפעיל את \'חיסכון בסוללה\'?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"התחל"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"הפעל את \'חיסכון בסוללה\'"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"כדי לעזור בהארכת חיי הסוללה, תכונת \'חיסכון בסוללה\' תצמצם את פעילות המכשיר.\n\nתכונת \'חיסכון בסוללה\' תושבת כשהמכשיר יחובר לחשמל."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"הגדרות"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"מצב טיסה"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"‏למשך %d שעות"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"תכונת \'חיסכון בסוללה\' פועלת"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"פעילות המכשיר צומצמה."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"פתח את ההגדרות של \'חיסכון בסוללה\'"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"התוכן מוסתר"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> יתחיל להקליט את כל התוכן המוצג במסך שלך."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"נקה הכל"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"התחל כעת"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"אין הודעות"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 280e7ed..2307b6e 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB充電には対応していません。"</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"専用の充電器のみを使用してください。"</string>
     <string name="battery_low_why" msgid="4553600287639198111">"設定"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"バッテリーセーバーを開始しますか?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"開始"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"バッテリーセーバーを開始"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"バッテリーを長持ちさせるため、バッテリーセーバーは端末のパフォーマンスを制限します。\n\n端末が電源に接続されているときはバッテリーセーバーが無効になります。"</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"設定"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"機内モード"</string>
@@ -288,8 +290,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d時間"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"バッテリーセーバーがON"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"端末のパフォーマンスが制限されています。"</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"バッテリーセーバーの設定を開く"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"コンテンツが非表示"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>で、画面に表示されているコンテンツのキャプチャを開始します。"</string>
@@ -297,4 +301,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"すべて消去"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"今すぐ開始"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"通知はありません"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 4d6b11b..331c4c8 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB დატენვა მხარდაჭერილი არ არის."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"გამოიყენეთ მხოლოდ მოყოლილი დამტენი."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"პარამეტრები"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"გსურთ ბატარეის დამზოგის დაწყება?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"დაწყება"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"ბატარეის დამზოგის დაწყება"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"ბატარეის მოქმედების გასახანგრძლივებლად ბატარეის დამზოგი შეამცირებს თქვენი მოწყობილობის წარმადობას.\n\nბატარეის დამზოგი გამოირთვება, როდესაც მოწყობილობას ელკვებაზე მიაერთებთ."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"პარამეტრები"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"თვითმფრინავის რეჟიმი"</string>
@@ -150,7 +152,7 @@
     <string name="accessibility_tty_enabled" msgid="4613200365379426561">"ტელეტაიპი ჩართულია."</string>
     <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"ვიბრაციის რეჟიმი."</string>
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"უხმო რეჟიმი."</string>
-    <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>-ის გაშვება."</string>
+    <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>-ის უგულებელყოფა."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ამოშლილია სიიდან."</string>
     <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> იწყება."</string>
     <string name="accessibility_notification_dismissed" msgid="854211387186306927">"შეტყობინება წაიშალა."</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d საათით"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"ბატარეის დამზოგი ჩართულია"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"მოწყობილობის წარმადობა შემცირებულია."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"ბატარეის დამზოგის პარამეტრების გახსნა"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"შიგთავსი დამალულია"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> დაიწყებს იმ ყველაფრის აღბეჭდვას, რაც თქვენს ეკრანზე ჩანს."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"ყველას გასუფთავება"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"დაწყება ახლავე"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"შეტყობინებები არ არის."</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index ad7a5ad..6991615 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB арқылы зарядтауға қолдау көрсетілмейді."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Тек жинақтағы зарядтағышты пайдаланыңыз."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Параметрлер"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Батарея үнемдегішті іске қосу керек пе?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Бастау"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Батарея үнемдегішті іске қосу"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Батареяның жарамды мерзімін жақсартуға көмектесу үшін батарея үнемдегіш құрылғының өнімділігін азайтады.\n\nБатарея үнемдегіш құрылғыңыз розеткаға қосылған болса өшеді."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Параметрлер"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Ұшақ режимі"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d сағат бойы"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Батарея үнемдегіш қосулы"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Құрылғы өнімділігі азайды."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Батарея үнемдегіш параметрлерін ашу"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Мазмұн жасырылған"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> экранда көрсетілгеннің барлығын түсіре бастайды."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Барлығын тазалау"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Қазір бастау"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Хабарландырулар жоқ"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 1b72d10..d9d8402 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"មិន​គាំទ្រ​ការ​បញ្ចូល​ថ្ម​តាម​យូអេសប៊ី​ទេ។"</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"ប្រើ​តែ​ឧបករណ៍​បញ្ចូល​ថ្ម​ដែល​បាន​ផ្ដល់​ឲ្យ។"</string>
     <string name="battery_low_why" msgid="4553600287639198111">"ការកំណត់"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"ចាប់ផ្ដើម​កម្មវិធី​សន្សំ​ថ្ម?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"ចាប់ផ្ដើម"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"ចាប់ផ្ដើម​កម្មវិធី​សន្សំ​ថ្ម"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"ដើម្បី​ជួយ​បង្កើន​អាយុកាល​ថ្ម កម្មវិធី​សន្សំ​ថ្ម​នឹង​កាត់បន្ថយ​ការ​អនុវត្ត​​នៃ​ឧបករណ៍​របស់​អ្នក។\n\nកម្មវិធី​សន្សំ​ថ្ម​នឹង​បិទ​នៅ​ពេល​ឧបករណ៍​របស់​អ្នក​ត្រូវ​បាន​ដោត​បញ្ចូល​ថ្ម។"</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"ការ​កំណត់"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"វ៉ាយហ្វាយ"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"ពេល​ជិះ​យន្តហោះ"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"សម្រាប់ %d ម៉ោង"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"កម្មវិធី​សន្សំ​ថ្ម​គឺ​បើក"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"ការ​អនុវត្ត​ឧបករណ៍​ត្រូវ​បាន​កាត់​បន្ថយ។"</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"បើក​ការ​កំណត់​កម្មវិធី​សន្សំ​ថ្ម"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"បាន​លាក់​មាតិកា"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> នឹង​ចាប់ផ្ដើម​ចាប់​យក​អ្វីៗ​គ្រប់យ៉ាង​ដែល​បង្ហាញ​លើ​អេក្រង់​របស់​អ្នក។"</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"សម្អាត​ទាំងអស់"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ចាប់ផ្ដើម​ឥឡូវ"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"គ្មាន​ការ​ជូនដំណឹង"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index 7d59e39..1bd31d2 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB ಚಾರ್ಜಿಂಗ್ ಬೆಂಬಲಿತವಾಗಿಲ್ಲ."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"ಒದಗಿಸಿರುವ ಚಾರ್ಜರ್ ಮಾತ್ರ ಬಳಸಿ."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"ಬ್ಯಾಟರಿ ರಕ್ಷಕ ಪ್ರಾರಂಭಿಸುವುದೇ?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"ಪ್ರಾರಂಭಿಸು"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"ಬ್ಯಾಟರಿ ರಕ್ಷಕವನ್ನು ಪ್ರಾರಂಭಿಸಿ"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"ಬ್ಯಾಟರಿ ಬಾಳಿಕೆಯನ್ನು ಸುಧಾರಿಸಲು, ಬ್ಯಾಟರಿ ರಕ್ಷಕ ನಿಮ್ಮ ಸಾಧನದ ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಕಡಿಮೆಗೊಳಿಸುತ್ತದೆ.\n\nನಿಮ್ಮ ಸಾಧನವನ್ನು ಪ್ಲಗ್ ಇನ್ ಮಾಡಿದಾಗ ಬ್ಯಾಟರಿ ರಕ್ಷಕ ನಿಷ್ಕ್ರಿಯಗೊಳ್ಳುತ್ತದೆ."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d ಗಂಟೆಗಳವರೆಗೆ"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"ಬ್ಯಾಟರಿ ರಕ್ಷಕ ಆನ್ ಆಗಿದೆ"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"ಸಾಧನದ ಕಾರ್ಯಕ್ಷಮತೆ ಕಡಿಮೆಯಾಗಿದೆ."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"ಬ್ಯಾಟರಿ ರಕ್ಷಕದ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"ವಿಷಯಗಳನ್ನು ಮರೆಮಾಡಲಾಗಿದೆ"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"ನಿಮ್ಮ ಪರದೆಯ ಮೇಲೆ ಪ್ರದರ್ಶಿಸಲಾಗುವ ಎಲ್ಲವನ್ನೂ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಯು ಸೆರೆಹಿಡಿಯಲು ಪ್ರಾರಂಭಿಸುತ್ತದೆ."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸು"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ಈಗ ಪ್ರಾರಂಭಿಸಿ"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"ಯಾವುದೇ ಅಧಿಸೂಚನೆಗಳಿಲ್ಲ"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 90fbfe9..a62d501 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -41,10 +41,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB 충전은 지원되지 않습니다."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"제공된 충전기만 사용하세요."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"설정"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"배터리 세이버를 시작할까요?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"시작"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"배터리 세이버 시작"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"배터리 세이버는 기기의 성능을 저하시켜 배터리 수명을 늘립니다.\n\n기기에 전원이 연결되면 배터리 세이버는 사용 중지됩니다."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"설정"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"비행기 모드"</string>
@@ -75,7 +77,7 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"캡쳐화면 저장됨"</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"캡쳐화면을 보려면 터치하세요."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"캡쳐화면을 캡쳐하지 못했습니다."</string>
-    <string name="screenshot_failed_text" msgid="1260203058661337274">"저장 공간이 부족하거나 앱 또는 소속 조직에서 허용하지 않기 때문에 스크린샷을 찍을 수 없습니다."</string>
+    <string name="screenshot_failed_text" msgid="1260203058661337274">"저장 공간이 부족하거나 앱 또는 소속 조직에서 허용하지 않아 스크린샷을 찍을 수 없습니다."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB 파일 전송 옵션"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"미디어 플레이어로 마운트(MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"카메라로 마운트(PTP)"</string>
@@ -288,8 +290,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d시간 동안"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"배터리 세이버 사용 중"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"기기의 성능이 저하됩니다."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"배터리 세이버 설정 열기"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"숨겨진 콘텐츠"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>에서 화면에 표시된 모든 것을 캡처하기 시작합니다."</string>
@@ -297,4 +301,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"모두 지우기"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"시작하기"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"알림 없음"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index 8bb2cab..750c1d9 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -46,10 +46,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB аркылуу кубаттоого болбойт."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Коштолгон кубаттагычты гана колдонуңуз."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Жөндөөлөр"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Батареяны үнөмдөгүч иштетилсинби?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Баштоо"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Батареяны үнөмдөгүчтү иштетүү"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Батареяны үнөмдөгүч түзмөгүңүздүн иштешин солгундатып, батареянын кубатын узартат.\n\nТүзмөктү кубаттагычка сайганда, батареяны үнөмдөгүч өчүп калат."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
     <skip />
     <!-- no translation found for status_bar_settings_wifi_button (1733928151698311923) -->
@@ -312,8 +314,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d саатка"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Батареяны үнөмдөгүч күйгүзүлдү"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Түзмөктүн иштеши солгундады."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Батареяны үнөмдөгүчтүн жөндөөлөрүн ачуу"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Мазмундар жашырылган"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> экранга чыккан нерсенин баарын сүрөткө тарта баштайт."</string>
@@ -321,4 +325,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Бардыгын тазалап салуу"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Азыр баштоо"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Эскертмелер жок"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-land/arrays.xml b/packages/SystemUI/res/values-land/arrays.xml
deleted file mode 100644
index c32ce12..0000000
--- a/packages/SystemUI/res/values-land/arrays.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/colors.xml
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <array name="navbar_search_targets">
-        <item>@null</item>
-        <item>@null</item>
-        <item>@drawable/ic_action_assist_generic</item>
-        <item>@null</item>
-    </array>
-
-    <array name="navbar_search_target_descriptions">
-        <item>@null</item>
-        <item>@null</item>
-        <item>@string/description_target_search</item>
-        <item>@null</item>
-    </array>
-
-    <array name="navbar_search_direction_descriptions">
-        <item>@null</item>
-        <item>@null</item>
-        <item>@string/description_direction_left</item>
-        <item>@null</item>
-    </array>
-
-</resources>
diff --git a/packages/SystemUI/res/values-land/config.xml b/packages/SystemUI/res/values-land/config.xml
index 5755029..2b1a4dc 100644
--- a/packages/SystemUI/res/values-land/config.xml
+++ b/packages/SystemUI/res/values-land/config.xml
@@ -24,9 +24,6 @@
      value at runtime for some things) -->
     <integer name="status_bar_recents_bg_gradient_degrees">90</integer>
 
-    <!-- The number of columns in the QuickSettings -->
-    <integer name="quick_settings_num_columns">4</integer>
-
     <!-- The maximum number of rows in the QuickSettings -->
     <integer name="quick_settings_max_rows">2</integer>
 
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index 42c4392..9b772bd 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -41,6 +41,7 @@
     <!-- The side padding for the task stack as a percentage of the width. -->
     <item name="recents_stack_width_padding_percentage" format="float" type="dimen">0.2229</item>
 
-    <!-- Width of the zen mode interstitial dialog. -->
-    <dimen name="zen_mode_dialog_width">384dp</dimen>
+    <!-- Standard notification width + gravity -->
+    <dimen name="notification_panel_width">@dimen/standard_notification_panel_width</dimen>
+    <integer name="notification_panel_layout_gravity">@integer/standard_notification_panel_layout_gravity</integer>
 </resources>
diff --git a/packages/SystemUI/res/values-land/styles.xml b/packages/SystemUI/res/values-land/styles.xml
index 8919198..682998d 100644
--- a/packages/SystemUI/res/values-land/styles.xml
+++ b/packages/SystemUI/res/values-land/styles.xml
@@ -18,4 +18,22 @@
     <style name="BrightnessDialogContainer" parent="@style/BaseBrightnessDialogContainer">
         <item name="android:layout_width">360dp</item>
     </style>
+
+    <style name="SearchPanelCard">
+        <item name="android:layout_width">@dimen/search_panel_card_height</item>
+        <item name="android:layout_height">match_parent</item>
+        <item name="android:layout_marginTop">16dp</item>
+        <item name="android:layout_marginBottom">16dp</item>
+        <item name="android:layout_gravity">right</item>
+    </style>
+
+    <style name="SearchPanelLogo">
+        <item name="android:layout_gravity">top|left</item>
+    </style>
+
+    <style name="SearchPanelScrim">
+        <item name="android:layout_width">@dimen/search_panel_scrim_height</item>
+        <item name="android:layout_height">match_parent</item>
+        <item name="android:layout_gravity">right</item>
+    </style>
 </resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index a3dac98..a433b85 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -39,10 +39,9 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"ບໍ່​ຮອງຮັບ​ການ​ສາກ​ຜ່ານ USB."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"ໃຊ້​ສະເພາະ​ສາຍ​ສາກ​ທີ່​ມາ​ກັບ​ເຄື່ອງ."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"​ການ​ຕັ້ງ​ຄ່າ"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"ເລີ່ມ​ໂຕປະຢັດ​ແບັດເຕີຣີ​ບໍ?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"ເລີ່ມ"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"ເລີ່ມ​ໂຕ​ປະຢັດ​ແບັດເຕີຣີ"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"ເພື່ອ​ຊ່ວຍ​ຢືດ​ອາຍຸ​ແບັດເຕີຣີ, ໂຕ​ປະຢັດ​ແບັດເຕີຣີ​ຈະ​ຫຼຸດ​ປະສິດທິພາບ​ຂອງ​ອຸປະກອນ​ທ່ານ​ລົງ.\n\nໂຕ​ປະຢັດ​ແບັດເຕີຣີ​ຈະ​ຖືກ​ປິດ​ການນຳໃຊ້​ໂດຍ​ອັດຕະໂນມັດ​ເມື່ອ​ທ່ານ​ສຽບ​ສາຍ​ສາກ​ອຸປະກອນ​ຂອງ​ທ່ານ."</string>
+    <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"ເປີດ​ໃຊ້​ການ​ປະ​ຢັດ​ແບັດ​ເຕີ​ຣີ​ບໍ?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"ເປີດ​ໃຊ້"</string>
+    <string name="battery_saver_start_action" msgid="5576697451677486320">"​ເປີດ​ໃຊ້​ໂຕ​ປະ​ຢັດ​ແບັດ​ເຕີ​ຣີ"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"ການຕັ້ງຄ່າ"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"ໂໝດເທິງຍົນ"</string>
@@ -286,8 +285,8 @@
     <item quantity="other" msgid="5408537517529822157">"ເປັນ​ເວລາ %d ຊົ່ວ​ໂມງ"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"ເປີດ​ໃຊ້​ໂຕ​ປະຢັດ​ແບັດເຕີຣີ​ແລ້ວ"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"ປະສິດທິພາບ​ຂອງ​ອຸປະກອນ​ຖືກ​ຫຼຸດ​ລົງ​ແລ້ວ."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"ເປີດ​ການ​ຕັ້ງຄ່າ​ໂຕ​ປະຢັດ​ແບັດເຕີຣີ"</string>
+    <string name="battery_saver_notification_text" msgid="820318788126672692">"ຫຼຸດ​ປະ​ສິ​ທິ​ພາບ​ແລະ​ການ​ນຳ​ໃຊ້​ຂໍ້​ມູນ​ພື້ນຫຼັງ"</string>
+    <string name="battery_saver_notification_action_text" msgid="109158658238110382">"ປິດ​ໂຕ​ປະ​ຢັດ​ແບັດ​ເຕີ​ຣີ"</string>
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"​ເນື້ອ​ຫາ​ຖືກ​ເຊື່ອງ​ແລ້ວ"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ​ຈະ​ເລີ່ມ​ບັນ​ທຶກ​ທຸກ​ຢ່າງ​ທີ່​ສະ​ແດງ​ຜົນ​ໃນ​ໜ້າ​ຈໍ​ທ່ານ."</string>
@@ -295,4 +294,15 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"ລຶບລ້າງທັງໝົດ"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ເລີ່ມດຽວນີ້"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"ບໍ່ມີການແຈ້ງເຕືອນ"</string>
+    <string name="device_owned_footer" msgid="3802752663326030053">"ອຸ​ປະ​ກອນ​ອາດ​ມີ​ການ​ເຝົ້າ​ຕິດ​ຕາມ"</string>
+    <string name="vpn_footer" msgid="2388611096129106812">"​ເຄືອ​ຂ່າຍ​ອາດ​ມີ​ການ​ເຝົ້າ​ຕິດ​ຕາມ"</string>
+    <string name="monitoring_title_device_owned" msgid="7121079311903859610">"ການກວດ​ສອບ​ຕິດ​ຕາມ​ອຸ​ປະ​ກອນ"</string>
+    <string name="monitoring_title" msgid="169206259253048106">"ການກວດ​ສອບ​ຕິດ​ຕາມ​ເຄືອ​ຂ່າຍ"</string>
+    <string name="open_app" msgid="4011771120339160755">"ເປີດແອັບຯ"</string>
+    <string name="disconnect_vpn" msgid="1324915059568548655">"ຕັດ​ການ​ເຊື່ອມ​ຕໍ່ VPN"</string>
+    <string name="monitoring_description_device_owned" msgid="7801926679066533391">"ອຸ​ປະ​ກອນ​ນີ້​ຖືກ​ຈັດ​ການ​ໂດຍ:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\n​ຜູ່​ເບິ່ງ​ແຍງ​ລະ​ບົບ​ສາ​ມາດ​ເຝົ້າ​ຕິດ​ຕາມ​ການ​ເຄື່ອນ​ໄຫວ​ເຄື​ອ​ຂ່າຍ​ຂອງ​ທ່ານ ຮວມ​ເຖິງ: ອີ​ເມວ, ແອັບຯ ແລະ​ເວັບ​ໄຊ​ທີ່​ເຂົ້າ​ລະ​ຫັດ.\n\nສຳ​ລັບ​ຂໍ້​ມູນ​ເພີ່ມ​ເຕີມ, ໃຫ້​ຕິດ​ຕໍ່​ຜູ່​ເບິ່ງ​ແຍງ​ລະ​ບົບ​ຂອງ​ທ່ານ."</string>
+    <string name="monitoring_description_vpn" msgid="93140751707065515">"​ທ່ານມອບ​ສິດ​ອະ​ນຸ​ຍາດໃຫ້ \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" ເພື່ອ​ຕັ້ງ​ຄ່າ​ການ​ເຊື່ອມ​ຕໍ່ VPN.\n\nແອັບຯ​ນີ້​ສາ​ມາດ​ເຝົ້າ​ຕິດ​ຕາມ​ການ​ເຄື່ອນ​ໄຫວ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ​ໄດ້ ຮວມ​ເຖິງ​ອີ​ເມວ, ແອັບຯ ແລະ​ເວັບ​ໄຊ​ທີ່​ເຂົ້າ​ລະ​ຫັດ."</string>
+    <string name="monitoring_description_legacy_vpn" msgid="5397847778080663075">"ທ່ານ​ເຊື່ອມ​ຕໍ່​ຫາ VPN ແລ້ວ (\"<xliff:g id="APPLICATION">%1$s</xliff:g>\").\n\nຜູ່​ໃຫ້​ບໍ​ລິ​ການ VPN ​ຂອງ​ທ່ານ​ສາ​ມາດ​ເຝົ້າ​ຕິດ​ຕາມ​ການ​ເຄື່ອນ​ໄຫວ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ​ໄດ້​ ຮວມ​ເຖິງອີ​ເມວ, ແອັບຯ ແລະ​ເວັບ​ໄຊ​ທີ່​ເຂົ້າ​ລະ​ຫັດ."</string>
+    <string name="monitoring_description_vpn_device_owned" msgid="696121105616356493">"ອຸ​ປະ​ກອນ​ຂອງ​ທ່ານ​ຖືກ​ຈັດ​ການ​ໂດຍ:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\n​ຜູ່​ເບິ່ງ​ແຍງ​ລະ​ບົບ​ຂອງ​ທ່ານ​ສາ​ມາດ​ເຝົ້າ​ຕິດ​ຕາມ​ການ​ເຄື່ອນ​ໄຫວ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ​ໄດ້ ຮວມ​ເຖິງ​ອີ​ເມວ, ແອັບຯ ແລະ​ເວັບ​ໄຊ​ທີ່​ເຂົ້າ​ລະ​​ຫັດ. ສຳ​ລັບ​ຂໍ້​ມູນ​ເພີ່ມ​ເຕີມ, ໃຫ້​ຕິດ​ຕໍ່​ຜູ່​ເບິ່ງ​ແຍງ​ລະ​ບົບ​ຂອງ​ທ່ານ.\n\nອີກ​ຢ່າງ​ນຶ່ງ, ທ່ານມອບ​ສິດ​ອະ​ນຸ​ຍາດໃຫ້ \"<xliff:g id="APPLICATION">%2$s</xliff:g>\" ເພື່ອ​ຕັ້ງ​ຄ່າ​ການ​ເຊື່ອມ​ຕໍ່ VPN. ແອັບຯ​ນີ້​ສາ​ມາດ​ເຝົ້າ​ຕິດ​ຕາມ​ການ​ເຄື່ອນ​ໄຫວ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ​ໄດ້."</string>
+    <string name="monitoring_description_legacy_vpn_device_owned" msgid="649791650224064248">"ອຸ​ປະ​ກອນ​ຂອງ​ທ່ານ​ຖືກ​ຈັດ​ການ​ໂດຍ:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\n​ຜູ່​ເບິ່ງ​ແຍງ​ລະ​ບົບ​ຂອງ​ທ່ານ​ສາ​ມາດ​ເຝົ້າ​ຕິດ​ຕາມ​ການ​ເຄື່ອນ​ໄຫວ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ​ໄດ້ ຮວມ​ເຖິງ​ອີ​ເມວ, ແອັບຯ ແລະ​ເວັບ​ໄຊ​ທີ່​ເຂົ້າ​ລະ​​ຫັດ. ສຳ​ລັບ​ຂໍ້​ມູນ​ເພີ່ມ​ເຕີມ, ໃຫ້​ຕິດ​ຕໍ່​ຜູ່​ເບິ່ງ​ແຍງ​ລະ​ບົບ​ຂອງ​ທ່ານ.\n\nນອກ​ຈາກ​ນັ້ນ, ທ່ານ​​ໄດ້​ເຊື່ອມ​ຕໍ່​ຫາ VPN (\"<xliff:g id="APPLICATION">%2$s</xliff:g>\"). ຜູ່​ໃຫ້​ບໍ​ລິ​ການ VPN ຂອງ​ທ່ານ​ສາ​ມາດ​ເຝົ້າ​ຕິດ​ຕາມ​ການ​ເຄື່ອນ​ໄຫວ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ​ໄດ້​ເຊັ່ນ​ກັນ."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index b88cdf9..3ea3f0b 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB įkrovimas nepalaikomas."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Naudokite tik pateiktą kroviklį."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Nustatymai"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Paleisti akumuliatoriaus tausojimo priemonę?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Paleisti"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Paleisti akumuliatoriaus tausojimo priemonę"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Kad padėtų pailginti akumuliatoriaus naudojimo trukmę, akumuliatoriaus tausojimo priemonė sumažins įrenginio našumą.\n\nAkumuliatoriaus tausojimo priemonė bus išjungta, kai įrenginys bus prijungtas prie maitinimo šaltinio."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Nustatymai"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Lėktuvo režimas"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d val."</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Akumuliatoriaus tausojimo priemonė įjungta"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Įrenginio našumas sumažintas."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Atidaryti akumuliatoriaus tausojimo priemonės nustatymus"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g> %%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Turinys paslėptas"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"„<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>“ pradės fiksuoti viską, kas rodoma jūsų ekrane."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Viską išvalyti"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Pradėti dabar"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nėra įspėjimų"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 93c9812..b9a4994 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB uzlāde netiek atbalstīta."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Izmantojiet tikai komplektā iekļauto lādētāju."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Iestatījumi"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Vai ieslēgt akumulatora enerģijas taupīšanas režīmu?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Ieslēgt"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Ieslēgt akumulatora enerģijas taupīšanas režīmu"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Lai paildzinātu akumulatora darbības laiku, akumulatora enerģijas taupīšanas režīmā tiks pazemināta ierīces veiktspēja.\n\nAkumulatora enerģijas taupīšanas režīms tiks atspējots, kad ierīce tiks pievienota uzlādes avotam."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Iestatījumi"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Lidmašīnas režīms"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d h"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Ieslēgts akumulatora enerģijas taupīšanas režīms"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Ierīces veiktspēja ir pazemināta."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Atvērt akumulatora enerģijas taupīšanas režīma iestatījumus"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Saturs paslēpts"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sāks uzņemt visu, kas tiks rādīts jūsu ekrānā."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Dzēst visu"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Sākt tūlīt"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nav paziņojumu"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index 83302fd..82adb40 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Полнењето преку УСБ не е поддржано."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Користете го само доставениот полнач."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Поставки"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Да се активира штедачот на батерија?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Започни"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Активирајте го штедачот на батерија"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"За да се подобри животот на батеријата, Штедачот на батерија ќе ја намали изведбата на вашиот уред.\n\nТој ќе се оневозможи кога уредот ќе се приклучи на полнење."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Подесувања"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Режим на работа во авион"</string>
@@ -288,8 +290,10 @@
     <item quantity="other" msgid="5408537517529822157">"За %d часа"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Штедачот на батерија е вклучен"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Изведбата на уредот е намалена."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Отвори ги поставките за штедачот на батерија"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Содржините се скриени"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ќе започне да презема сѐ што се прикажува на вашиот екран."</string>
@@ -297,4 +301,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Исчисти сè"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Започни сега"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Нема известувања"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index 87aedfa..06f5190 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB ചാർജ്ജുചെയ്യൽ പിന്തുണച്ചില്ല."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"വിതരണം ചെയ്‌ത ചാർജ്ജർ മാത്രം ഉപയോഗിക്കുക."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"ക്രമീകരണങ്ങൾ"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"ബാറ്ററി സേവർ ആരംഭിക്കണോ?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"ആരംഭിക്കുക"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"ബാറ്ററി സേവർ ആരംഭിക്കുക"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"ബാറ്ററി ആയുസ്സ് മെച്ചപ്പെടുത്താൻ സഹായിക്കുന്നതിന്, നിങ്ങളുടെ ഉപകരണത്തിന്റെ പ്രകടനത്തെ ബാറ്ററി സേവർ കുറയ്‌ക്കും.\n\nനിങ്ങളുടെ ഉപകരണം പ്ലഗ് ഇൻ ചെയ്‌തിരിക്കുമ്പോൾ ബാറ്ററി സേവർ അത് പ്രവർത്തനരഹിതമാക്കും."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"ക്രമീകരണങ്ങൾ"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"വിമാന മോഡ്"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d മണിക്കൂർ ദൈർഘ്യം"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"ബാറ്ററി സേവർ ഓണാണ്"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"ഉപകരണത്തിന്റെ പ്രകടനം കുറച്ചു."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"ബാറ്ററി സേവർ ക്രമീകരണങ്ങൾ തുറക്കുക"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"കോൺടാക്‌റ്റുകൾ മറച്ചു"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"നിങ്ങളുടെ സ്ക്രീനിൽ പ്രദർശിപ്പിച്ചിരിക്കുന്ന എല്ലാ കാര്യങ്ങളും <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ക്യാപ്‌ചർ ചെയ്യുന്നത് ആരംഭിക്കും."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"എല്ലാം മായ്‌ക്കുക"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ഇപ്പോൾ ആരംഭിക്കുക"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"അറിയിപ്പുകൾ ഒന്നുമില്ല"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 44aa796..0faf210 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB-р цэнэглэх дэмжигддэггүй."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Зөвхөн зориулалтын ирсэн цэнэглэгч ашиглана уу."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Тохиргоо"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Батерей хэмнэгчийг эхлүүлэх үү?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Эхлэх"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Батерей хэмнэгчийг эхлүүлэх"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Батарейны ашиглалтыг уртасгахын тулд Батарей хэмнэгч нь таны төхөөрөмжийн ажиллагааг бууруулах болно.\n\nБатарей хэмнэгч нь та төхөөрөмжөө цэнэглэх үед унтарна."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Тохиргоо"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Нислэгийн горим"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d цагийн турш"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Батерей хэмнэгч асаалттай"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Төхөөрөмжийн ажиллагааг бууруулсан."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Батерей хэмнэгчийн тохиргоог нээх"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Контентыг нуусан"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> таны дэлгэц дээр гаргасан бүх зүйлийн зургийг авч эхэлнэ."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Бүгдийг арилгах"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Одоо эхлүүлэх"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Мэдэгдэл байхгүй"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index 51f0797..d670ab6 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB चार्जिंग समर्थित नाही."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"केवळ पुरविलेले चार्जर वापरा."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"सेटिंग्ज"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"बॅटरी बचतकर्ता प्रारंभ करायचा?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"प्रारंभ करा"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"बॅटरी बचतकर्ता प्रारंभ करा"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"बॅटरी आयुष्य सुधारण्यात मदत करण्यासाठी, बॅटरी बचतकर्ता आपल्या डिव्हाइसचे कार्यप्रदर्शन कमी करेल. \n \n आपले डिव्हाइस प्लग इन केलेले असते तेव्हा बॅटरी बचतकर्ता अक्षम केला जाईल."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"सेटिंग्ज"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"विमान मोड"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d तासांसाठी"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"बॅटरी बचतकर्ता चालू आहे"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"डिव्‍हाइस कार्यप्रदर्शन कमी झाले आहे."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"बॅटरी बचतकर्ता सेटिंग्‍ज उघडा"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"लपविलेली सामग्री"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> आपल्‍या स्‍क्रीनवर प्रदर्शित होणारी प्रत्‍येक गोष्‍ट कॅप्‍चर करणे प्रारंभ करेल."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"सर्व साफ करा"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"आता प्रारंभ करा"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"सूचना नाहीत"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 4d5be08..93acf79 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Pengecasan USB tidak disokong."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Gunakan pengecas yang dibekalkan sahaja."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Tetapan"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Mulakan penjimat bateri?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Mula"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Mulakan penjimat bateri"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Untuk membantu meningkatkan hayat bateri, penjimat Bateri akan mengurangkan prestasi peranti anda.\n\nPenjimat bateri akan dilumpuhkan apabila peranti anda disambungkan kepada sumber kuasa."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Tetapan"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Mod pesawat"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"Selama %d jam"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Penjimat bateri dihidupkan"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Prestasi peranti dikurangkan."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Buka tetapan penjimat bateri"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Kandungan tersembunyi"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> akan mula mengabadikan semua yang dipaparkan pada skrin anda.."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Kosongkan semua"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Mulakan sekarang"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Tiada pemberitahuan"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index 09f6cbe..52883dd 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -37,10 +37,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB အားသွင်းမှု မပံ့ပိုးပါ။"</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"ပေးခဲ့သည့် အားသွင်းစက်ကိုသာ အသုံးပြုပါ"</string>
     <string name="battery_low_why" msgid="4553600287639198111">"ဆက်တင်များ"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"ဘက်ထရီ ချွေတာသူကို စဖွင့်ရမလား?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"စတင်ရန်"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"ဘက်ထရီ ချွေတာသူ စတင်ရန်"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"ဘက်ထရီ သက်တမ်း မြှင့်တင်ရန်၊ ဘက်ထရီ ချွေတာသူက သင့် ကိရိယာ၏ လုပ်ကိုင်မှုကို လျှော့ချမည်။ \n\n ကိရိယာကို ပလပ် ထိုးလိုက်လျှင် ဘက်ထရီ ချွေတာသူမှာ ပိတ်သွားမည်။"</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"အပြင်အဆင်များ"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"ဝိုင်ဖိုင်"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"လေယာဥ်ပျံပေါ်အသုံးပြုသောစနစ်"</string>
@@ -282,8 +284,10 @@
     <!-- String.format failed for translation -->
     <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
     <string name="battery_saver_notification_title" msgid="237918726750955859">"ဘက်ထရီ ချွေတာသူ ဖွင့်ထား"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"ကိရိယာ လုပ်ကိုင်မှုကို လျှော့ချခဲ့"</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"ဘက်ထရီ ချွေတာသူ ဆက်တင်များကို ဖွင့်ရန်"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"အကြောင်းအရာများ ဝှက်ထား"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> က သင်၏ မျက်နှာပြင် ပေါ်မှာ ပြသထားသည့် အရာတိုင်းကို စတင် ဖမ်းယူမည်။"</string>
@@ -291,4 +295,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"အားလုံး ရှင်းလင်းရန်"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ယခု စတင်ပါ"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"အကြောင်းကြားချက်များ မရှိ"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 07a63a2..2690ceb 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Lading via USB støttes ikke."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Bruk bare den tilhørende laderen."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Innstillinger"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Vil du starte batterisparing?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Start"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Start batterisparing"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"For å spare batteritid reduserer Batterisparing enhetens ytelse.\n\nBatterisparing deaktiveres når enheten er koblet til en lader."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Innstillinger"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Trådløse nettverk"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Flymodus"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"I %d timer"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Batterisparing er på"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Enhetsytelsen er redusert."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Åpen innstilling for batterisparing"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g> %%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Innholdet er skjult"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tar opp alt som vies på skjermen din."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Fjern alt"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Start nå"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ingen varsler"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 05f5ce8..2e45f22 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB चार्ज समर्थित छैन।"</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"आपूर्ति गरिएको चार्जर मात्र प्रयोग गर्नुहोस्।"</string>
     <string name="battery_low_why" msgid="4553600287639198111">"सेटिङ्हरू"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"ब्याट्रि सेभर सुरु गर्ने?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"सुरु गर्नुहोस्"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"ब्याट्रि सेभर सुरु भयो"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"ब्याट्रि जीवन सुधार गर्न, ब्याट्री सेभरले आफ्नो उपकरणको कार्य क्षमता कम गर्ने छ।\n\nआफ्नो उपकरण जोडिएको समयमा ब्याट्रि सेभर असक्षम गरिने छ।"</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"सेटिङहरू"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"वाइफाइ"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"हवाइजहाज मोड"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d घण्टाको लागि"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"ब्याट्रि सेभर चालु छ"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"उपकरण कार्य क्षमता कम छ।"</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"ब्याट्री सेभर सेटिङ्हरू खुला गर्नुहोस्"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"लुकेका सामाग्रीहरू"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ले आफ्नो स्क्रीनमा प्रदर्शित हुने सबै खिच्न शुरू गर्नेछ।"</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"सबै हटाउनुहोस्"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"अहिले सुरु गर्नुहोस्"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"कुनै सूचनाहरू छैनन्"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index dcbe984..0f59a3f 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Opladen via USB wordt niet ondersteund."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Gebruik alleen de bijgeleverde oplader."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Instellingen"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Accubesparing starten?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Starten"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Accubesparing starten"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Om de gebruiksduur van de accu te verbeteren, beperkt Accubesparing de prestaties van uw apparaat.\n\nAccubesparing wordt uitgeschakeld wanneer uw apparaat wordt aangesloten op een stopcontact."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Instellingen"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wifi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Vliegmodus"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d uur"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Accubesparing is ingeschakeld"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"De prestaties van het apparaat worden beperkt."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Instellingen voor Accubesparing openen"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Inhoud verborgen"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> gaat alles vastleggen dat wordt weergegeven op uw scherm."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Alles wissen"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Nu starten"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Geen meldingen"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 56765e8..d301248 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Ładowanie przez USB nie jest obsługiwane."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Używaj tylko ładowarki dostarczonej z urządzeniem."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Ustawienia"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Włączyć oszczędzanie baterii?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Włącz"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Włącz oszczędzanie baterii"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Funkcja oszczędzania baterii zmniejszy szybkość działania urządzenia, by ograniczyć wykorzystanie energii.\n\nOszczędzanie baterii wyłączy się, kiedy urządzenie będzie podłączone do źródła zasilania."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Ustawienia"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Tryb samolotowy"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"Przez %d godz."</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Oszczędzanie baterii jest włączone"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Urządzenie działa z ograniczoną szybkością."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Otwórz ustawienia oszczędzania baterii"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Treści ukryte"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> będzie zapisywać wszystko, co wyświetli się na ekranie."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Usuń wszystkie"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Rozpocznij teraz"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Brak powiadomień"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index b287a85..c06f267 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"O carregamento por USB não é suportado."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Utilize apenas o carregador fornecido."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Definições"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Iniciar a poupança de bateria?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Iniciar"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Iniciar a poupança de bateria"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Para ajudar a aumentar a duração da bateria, a Poupança de bateria reduzirá o desempenho do seu dispositivo.\n\nA Poupança de bateria será desativada assim que o dispositivo for ligado à corrente elétrica."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Definições"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Modo de avião"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"Durante %d horas"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"A poupança de bateria está ligada"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"O desempenho do dispositivo é reduzido."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Abrir as definições de poupança de bateria"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Conteúdo oculto"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"O(a) <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vai começar a captar tudo o que é apresentado no ecrã."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Limpar tudo"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Começar agora"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Sem notificações"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 8357280..87c501f 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"O carregamento via USB não é suportado."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Use apenas o carregador fornecido."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Configurações"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Iniciar a economia de bateria?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Iniciar"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Iniciar economia de bateria"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Para ajudar a melhorar a vida útil da bateria, a Economia de bateria reduzirá o desempenho do dispositivo.\n\nA Economia de bateria será desativada quando o dispositivo estiver carregando."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Configurações"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Modo avião"</string>
@@ -288,8 +290,10 @@
     <item quantity="other" msgid="5408537517529822157">"Por %d horas"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"A Economia de bateria está ativada"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"O desempenho do dispositivo foi reduzido."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Abrir configurações de economia de bateria"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Conteúdo oculto"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> começará a capturar tudo o que for exibido na tela."</string>
@@ -297,4 +301,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Limpar tudo"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Iniciar agora"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Sem notificações"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index ee03635..a5736af 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Încărcarea prin USB nu este acceptată."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Utilizați numai încărcătorul furnizat."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Setări"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Porniți economisirea bateriei?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Începeți"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Porniți economisirea bateriei"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Pentru a mări autonomia bateriei, funcția Economisirea bateriei reduce performanța dispozitivului.\n\nEconomisirea bateriei se dezactivează când dispozitivul este conectat la priză."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Setări"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Mod Avion"</string>
@@ -292,8 +294,10 @@
     <item quantity="other" msgid="5408537517529822157">"Timp de %d (de) ore"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Economisirea bateriei este activată"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Performanța dispozitivului s-a redus."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Deschideți setările pentru economisirea bateriei"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Conținutul este ascuns"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> va începe să captureze tot ceea ce se afișează pe ecran."</string>
@@ -301,4 +305,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Ștergeți toate notificările"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Începeți acum"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nicio notificare"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index d0f0a0c..e8900fe 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Зарядка через USB не поддерживается."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Используйте только зарядное устройство, поставляемое в комплекте с устройством."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Настройки"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Включить режим энергосбережения?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"ОК"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Включить режим энергосбережения"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Для экономии заряда батареи производительность устройства будет снижена.\n\nКогда устройство заряжается, режим энергосбережения отключен."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Настройки"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Режим полета"</string>
@@ -288,13 +290,37 @@
     <item quantity="other" msgid="5408537517529822157">"%d ч."</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Включен режим энергосбережения"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Производительность устройства снижена."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Открыть настройки режима энергосбережения"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Содержимое скрыто"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"Приложение <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> получит доступ к изображению на экране устройства."</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Больше не показывать"</string>
-    <string name="clear_all_notifications_text" msgid="814192889771462828">"Удалить все"</string>
+    <string name="clear_all_notifications_text" msgid="814192889771462828">"Очистить все"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Начать"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Нет уведомлений"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index 37a4236..6dd4a57 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB ආරෝපණය කිරීම සහාය නොදක්වයි."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"සපයන ලද අරෝපකය පමණක් භාවිතා කරන්න."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"සැකසීම්"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"බැටරි සුරැකීම ආරම්භ කරන්නද?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"ආරම්භ කරන්න"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"බැටරි ඉතිරි කරන්නා ආරම්භ කරන්න"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"බැටරියේ ජීව දියුණු කිරීමට, බැටරි ඉතිරි කරන්නා ඔබගේ උපාංගයේ ක්‍රියාකාරිත්වය අඩු කරයි.\n\nඔබගේ උපාංගය පේනුගත කර ඇති විට බැටරි ඉතිරි කරන්නා අබල වේ."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"සැකසීම්"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"අහස්යානා ආකාරය"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"පැය %d ක් සඳහා"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"බැටරි ඉතිරි කරන්නා සක්‍රීයයි"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"උපාංගය ක්‍රියාකාරිත්වය අඩු කරන ලදී."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"බැටරි ඉතිරි කරන්නා සැකසීම් විවෘත කරන්න"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"සැඟවුණු සම්බන්ධතා"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"ඔබගේ තීරයේ දර්ශනය වන සෑම දෙයම <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ලබාගැනීම ආරම්භ කරන ලදි."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"සියල්ල හිස් කරන්න"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"දැන් අරඹන්න"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"දැනුම්දීම් නැත"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 2797f14..516a9ac 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -39,10 +39,9 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Nabíjanie prostredníctvom USB nie je podporované."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Používajte iba originálnu nabíjačku."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Nastavenia"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Chcete spustiť šetrič batérie?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Spustiť"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Spustiť šetrič batérie"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Šetrič batérie zníži výkonnosť vášho zariadenia, aby tak predĺžil výdrž batérie.\n\nPo pripojení zariadenia do zásuvky sa šetrič batérie deaktivuje."</string>
+    <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"Zapnúť šetrič batérie?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"Zapnúť"</string>
+    <string name="battery_saver_start_action" msgid="5576697451677486320">"Zapnúť šetrič batérie"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Nastavenia"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Režim V lietadle"</string>
@@ -288,8 +287,8 @@
     <item quantity="other" msgid="5408537517529822157">"Na %d h"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Šetrič batérie je zapnutý"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Výkonnosť zariadenia sa znížila."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Otvorte nastavenia šetriča batérie"</string>
+    <string name="battery_saver_notification_text" msgid="820318788126672692">"Obmedzí výkonnosť a prenos údajov na pozadí"</string>
+    <string name="battery_saver_notification_action_text" msgid="109158658238110382">"Vypnúť šetrič batérie"</string>
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g> %%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Skrytý obsah"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"Aplikácia <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> začne zaznamenávať všetok obsah zobrazený na vašej obrazovke."</string>
@@ -297,4 +296,15 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Vymazať všetko"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Spustiť"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Žiadne upozornenia"</string>
+    <string name="device_owned_footer" msgid="3802752663326030053">"Zariadenie môže byť sledované"</string>
+    <string name="vpn_footer" msgid="2388611096129106812">"Sieť môže byť sledovaná"</string>
+    <string name="monitoring_title_device_owned" msgid="7121079311903859610">"Sledovanie zariadenia"</string>
+    <string name="monitoring_title" msgid="169206259253048106">"Sledovanie siete"</string>
+    <string name="open_app" msgid="4011771120339160755">"Otvoriť aplikáciu"</string>
+    <string name="disconnect_vpn" msgid="1324915059568548655">"Odpojiť sieť VPN"</string>
+    <string name="monitoring_description_device_owned" msgid="7801926679066533391">"Toto zariadenie spravuje organizácia:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nSprávca môže sledovať vašu aktivitu v sieti vrátane e-mailov, aplikácií a zabezpečených webových stránok.\n\nĎalšie informácie získate od svojho správcu."</string>
+    <string name="monitoring_description_vpn" msgid="93140751707065515">"Aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> ste povolili nastaviť pripojenie VPN.\n\nTáto aplikácia môže sledovať vašu aktivitu v sieti vrátane e-mailov, aplikácií a zabezpečených webových stránok."</string>
+    <string name="monitoring_description_legacy_vpn" msgid="5397847778080663075">"Ste pripojený/-á k sieti VPN (<xliff:g id="APPLICATION">%1$s</xliff:g>).\n\nPoskytovateľ služby VPN môže sledovať vašu aktivitu v sieti vrátane e-mailov, aplikácií a zabezpečených webových stránok."</string>
+    <string name="monitoring_description_vpn_device_owned" msgid="696121105616356493">"Toto zariadenie spravuje organizácia:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nSprávca môže sledovať vašu aktivitu v sieti vrátane e-mailov, aplikácií a zabezpečených webových stránok. Ďalšie informácie získate od svojho správcu.\n\nZároveň ste aplikácii <xliff:g id="APPLICATION">%2$s</xliff:g> povolili nastaviť pripojenie VPN. Táto aplikácia môže tiež sledovať vašu aktivitu v sieti."</string>
+    <string name="monitoring_description_legacy_vpn_device_owned" msgid="649791650224064248">"Toto zariadenie spravuje organizácia:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nSprávca môže sledovať vašu aktivitu v sieti vrátane e-mailov, aplikácií a zabezpečených webových stránok. Ďalšie informácie získate od svojho správcu.\n\nZároveň ste pripojený/-á aj k sieti VPN (<xliff:g id="APPLICATION">%2$s</xliff:g>). Poskytovateľ služby VPN môže tiež sledovať vašu aktivitu v sieti."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 29783f9..d67b646 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Polnjenje prek USB-ja ni podprto."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Uporabljajte samo priloženi polnilnik."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Nastavitve"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Želite zagnati varčevanje z energijo akumulatorja?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Začni"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Zaženi varčevanje z energijo akumulatorja"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Zaradi podaljšanja delovanja akumulatorja funkcija Varčevanje z energijo akumulatorja zmanjša zmogljivost delovanja naprave.\n\nVarčevanje z energijo akumulatorja se onemogoči, ko je naprava priklopljena na zunanje napajanje."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Nastavitve"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Način za letalo"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"Za %d h"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Varčevanje z energijo akumulatorja je vklopljeno"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Zmogljivost delovanja naprave je zmanjšana."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Odpri nastavitve varčevanja z energijo akumulatorja"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Vsebina je skrita"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"Aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> bo začela zajemati vse, kar je prikazano na zaslonu."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Izbriši vse"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Začni zdaj"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ni obvestil"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 391bba8..b1712f9 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Пуњење преко USB-а није подржано."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Користите само пуњач који сте добили."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Подешавања"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Желите ли да покренете Штедњу батерије?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Покрени"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Покрените Штедњу батерије"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Да би продужила век трајања батерије, Штедња батерије умањује перформансе уређаја.\n\nШтедња батерије ће се искључити када прикључите уређај на напајање."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Подешавања"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Режим рада у авиону"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d с"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Штедња батерије је укључена"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Перформансе уређаја су умањене."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Отворите подешавања Штедње батерије"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Садржај је сакривен"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ће почети да снима све што се приказује на екрану."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Обриши све"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Започни одмах"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Нема обавештења"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 044b9ab..09efed1 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Det finns inget stöd för laddning via USB."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Använd endast den medföljande laddaren."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Inställningar"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Vill du aktivera batterisparläget?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Börja"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Aktivera batterisparläget"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Med batterisparläget minskas enhetens prestanda i syfte att förlänga batteritiden.\n\nBatterisparläget inaktiveras när enheten ansluts till ett uttag."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Inställningar"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Flygplansläge"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"I %d timmar"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Batterisparläget har aktiverats"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Enhetens prestanda har minskats."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Öppna inställningarna för batterisparläget"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Innehåll har dolts"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tar en bild av allt som visas på skärmen."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Rensa alla"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Starta nu"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Inga aviseringar"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 54430ad..f5425bc 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -37,10 +37,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Kuchaji kwa kutumia USB hakutumiki."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Tumia chaja iliyonunuliwa pamoja na kifaa pekee."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Mipangilio"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Ungependa kuwasha kiokoa betri?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Anza"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Washa kiokoa betri"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Ili kusaidia kuboresha muda wa matumizi ya betri, Kiokoa betri kitapunguza utendaji wa kifaa chako.\n\nKiokoa betri kitazimwa kifaa chako kitakapochomekwa kwenye nishati ya umeme."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Mipangilio"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Mtandao-Hewa"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Hali ya Ndege"</string>
@@ -243,7 +245,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"tafuta"</string>
     <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Betri imejaa"</string>
     <string name="expanded_header_battery_charging" msgid="205623198487189724">"Inachaji"</string>
-    <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> hadi ijae"</string>
+    <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"Imebakisha <xliff:g id="CHARGING_TIME">%s</xliff:g> ijae"</string>
     <string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"Haichaji"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Huenda mtandao\nunafuatiliwa"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Tafuta"</string>
@@ -265,7 +267,7 @@
     <string name="interruption_level_none" msgid="3831278883136066646">"Hamna"</string>
     <string name="interruption_level_priority" msgid="6517366750688942030">"Kipaumbele"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Zote"</string>
-    <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Inachaji ( <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hadi ijae)"</string>
+    <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Inachaji (Imebakisha <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ijae)"</string>
     <string name="guest_nickname" msgid="8059989128963789678">"Aliyealikwa"</string>
     <string name="guest_new_guest" msgid="4259024453643879653">"+ Aliyealikwa"</string>
     <string name="guest_exit_guest" msgid="1619100760451149682">"Ondoa aliyealikwa"</string>
@@ -284,8 +286,10 @@
     <item quantity="other" msgid="5408537517529822157">"Kwa saa %d"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Kiokoa betri kimewashwa"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Utendaji wa kifaa umepunguzwa."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Fungua mipangilio ya hali inayookoa betri"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Maudhui yamefichwa"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> itaanza kupiga picha kila kitu kinachoonyeshwa kwenye skrini yako."</string>
@@ -293,4 +297,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Futa zote"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Anza sasa"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Hakuna arifa"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp/arrays.xml b/packages/SystemUI/res/values-sw600dp/arrays.xml
deleted file mode 100644
index 21c4bd3..0000000
--- a/packages/SystemUI/res/values-sw600dp/arrays.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/colors.xml
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <array name="navbar_search_targets">
-        <item>@null</item>
-        <item>@drawable/ic_action_assist_generic</item>
-        <item>@null</item>
-        <item>@null</item>
-    </array>
-
-    <array name="navbar_search_target_descriptions">
-        <item>@null</item>
-        <item>@string/description_target_search</item>
-        <item>@null</item>
-        <item>@null</item>
-    </array>
-
-    <array name="navbar_search_direction_descriptions">
-        <item>@null</item>
-        <item>@string/description_direction_left</item>
-        <item>@null</item>
-        <item>@null</item>
-    </array>
-
-</resources>
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
index 9f4c364..4f6d209 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -20,9 +20,6 @@
 <!-- These resources are around just to allow their values to be customized
      for different hardware and product builds. -->
 <resources>
-    <!-- The number of columns in the QuickSettings -->
-    <integer name="quick_settings_num_columns">4</integer>
-
     <!-- The maximum number of rows in the QuickSettings -->
     <integer name="quick_settings_max_rows">4</integer>
 
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 953a3ab..2d82d6e 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -16,12 +16,9 @@
 */
 -->
 <resources>
-    <!-- The width of the notification panel window: 400 + 16 + 16 (padding in the bg drawable) -->
-    <dimen name="notification_panel_width">432dp</dimen>
-
-    <!-- Gravity for the notification panel -->
-    <!-- 0x31 = top|center_horizontal -->
-    <integer name="notification_panel_layout_gravity">0x31</integer>
+    <!-- Standard notification width + gravity -->
+    <dimen name="notification_panel_width">@dimen/standard_notification_panel_width</dimen>
+    <integer name="notification_panel_layout_gravity">@integer/standard_notification_panel_layout_gravity</integer>
 
     <!-- Diameter of outer shape drawable shown in navbar search-->
     <dimen name="navbar_search_outerring_diameter">430dip</dimen>
@@ -49,9 +46,6 @@
     <!-- The side padding for the task stack as a percentage of the width. -->
     <item name="recents_stack_width_padding_percentage" format="float" type="dimen">0.075</item>
 
-    <!-- Width of the zen mode interstitial dialog. -->
-    <dimen name="zen_mode_dialog_width">384dp</dimen>
-
     <!-- The fraction of the screen height where the clock on the Keyguard has its center. The
          max value is used when no notifications are displaying, and the min value is when the
          highest possible number of notifications are showing. -->
@@ -80,4 +74,12 @@
 
     <!-- end margin for system icons if multi user switch is hidden -->
     <dimen name="system_icons_switcher_hidden_expanded_margin">20dp</dimen>
+
+    <!-- The width/height of the phone/camera/unlock icon on keyguard. -->
+    <dimen name="keyguard_affordance_height">80dp</dimen>
+    <dimen name="keyguard_affordance_width">120dp</dimen>
+
+    <!-- The width of the region on the left/right edge of the screen for performing the camera/
+     phone hints. -->
+    <dimen name="edge_tap_area_width">80dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp/styles.xml b/packages/SystemUI/res/values-sw600dp/styles.xml
index d4a9986..5daf08e 100644
--- a/packages/SystemUI/res/values-sw600dp/styles.xml
+++ b/packages/SystemUI/res/values-sw600dp/styles.xml
@@ -19,14 +19,19 @@
         <item name="android:layout_width">480dp</item>
     </style>
 
-    <style name="NotificationsQuickSettings">
-        <item name="android:layout_width">@dimen/notification_panel_width</item>
-        <item name="android:layout_height">match_parent</item>
+    <style name="SearchPanelCard">
+        <item name="android:layout_width">550dp</item>
+        <item name="android:layout_height">@dimen/search_panel_card_height</item>
+        <item name="android:layout_gravity">center_horizontal|bottom</item>
+    </style>
+
+    <style name="SearchPanelLogo">
         <item name="android:layout_gravity">top|center_horizontal</item>
     </style>
 
-    <style name="StatusBarHeader">
-        <item name="android:layout_width">@dimen/notification_panel_width</item>
-        <item name="android:layout_gravity">center_horizontal</item>
+    <style name="SearchPanelScrim">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">@dimen/search_panel_scrim_height</item>
+        <item name="android:layout_gravity">bottom</item>
     </style>
 </resources>
diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml
index 7695b12..3cd5f67 100644
--- a/packages/SystemUI/res/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp/dimens.xml
@@ -22,12 +22,8 @@
          be situations where they don't sync up perfectly with PhoneStatusBar. -->
     <!-- ======================================== -->
 
-    <!-- The width of the ticker, including the icon -->
-    <dimen name="notification_ticker_width">360dp</dimen>
     <!-- gap on either side of status bar notification icons -->
     <dimen name="status_bar_icon_padding">1dp</dimen>
-    <!-- The width of the notification panel window -->
-    <dimen name="notification_panel_width">512dp</dimen>
     <!-- The minimum height of the notification panel window -->
     <dimen name="notification_panel_min_height">770dp</dimen>
     <!-- Bottom margin (from display edge) for status bar panels -->
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 6100497..2d46822 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB சார்ஜிங் ஆதரிக்கப்படவில்லை."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"வழங்கப்பட்ட சார்ஜரை மட்டும் பயன்படுத்துக."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"அமைப்புகள்"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"பேட்டரி சேமிப்பானைத் தொடங்கவா?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"தொடங்கு"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"பேட்டரி சேமிப்பானைத் தொடங்கு"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"பேட்டரியின் ஆயுட்காலத்தை அதிகரிக்க, பேட்டரி சேமிப்பான் சாதனத்தின் செயல்திறனைக் குறைக்கும்.\n\nசாதனம் சாதனம் சார்ஜ் ஆகும் போது, பேட்டரி சேமிப்பான் முடக்கப்படும்."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"அமைப்புகள்"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"வைஃபை"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"விமானப் பயன்முறை"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d மணிநேரம்"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"பேட்டரி சேமிப்பான் இயக்கத்தில் உள்ளது"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"சாதன செயல்திறன் குறைக்கப்பட்டது."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"பேட்டரி சேமிப்பான் அமைப்புகளைத் திற"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"மறைந்துள்ள உள்ளடக்கம்"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"திரையில் காட்டப்படும் அனைத்தையும் <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> படமெடுக்கும்."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"எல்லாவற்றையும் அழி"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"இப்போது தொடங்கு"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"அறிவிப்புகள் இல்லை"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index 6aa8500..a41bd75 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB ఛార్జింగ్‌కి మద్దతు లేదు."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"అందించిన ఛార్జర్‌ను మాత్రమే ఉపయోగించండి."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"సెట్టింగ్‌లు"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"బ్యాటరీ సేవర్‌ను ప్రారంభించాలా?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"ప్రారంభించు"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"బ్యాటరీ సేవర్‌ను ప్రారంభించు"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"బ్యాటరీ జీవిత కాలం పెంచడంలో సహాయపడటానికి, బ్యాటరీ సేవర్ మీ పరికరం పనితీరును తగ్గిస్తుంది.\n\nమీ పరికరాన్ని ప్లగిన్ చేసినప్పుడు బ్యాటరీ సేవర్ నిలిపివేయబడుతుంది."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"సెట్టింగ్‌లు"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"ఎయిర్‌ప్లేన్ మోడ్"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d గంటలకు"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"బ్యాటర్ సేవర్ ఆన్ చేయబడింది"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"పరికరం పనితీరు తగ్గించబడింది."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"బ్యాటరీ సేవర్ సెట్టింగ్‌లను తెరువు"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"కంటెంట్‌లు దాచబడ్డాయి"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> మీ స్క్రీన్‌పై కనిపించే ప్రతిదాన్ని క్యాప్చర్ చేయడం ప్రారంభిస్తుంది."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"అన్నీ క్లియర్ చేయండి"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ఇప్పుడే ప్రారంభించు"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"నోటిఫికేషన్‌లు లేవు"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index a1126df..ec35d9e 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"ไม่รองรับการชาร์จผ่าน USB"</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"ใช้เฉพาะที่ชาร์จที่ให้มา"</string>
     <string name="battery_low_why" msgid="4553600287639198111">"การตั้งค่า"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"เริ่มใช้โหมดประหยัดแบตเตอรี่ใช่ไหม"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"เริ่ม"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"เริ่มโหมดประหยัดแบตเตอรี่"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"เพื่อช่วยให้ใช้งานแบตเตอรี่ได้ยาวนานขึ้น โหมดประหยัดแบตเตอรี่จะลดประสิทธิภาพการทำงานของอุปกรณ์ลง\n\nโหมดประหยัดแบตเตอรี่จะปิดเมื่อคุณเสียบปลั๊กไฟกับอุปกรณ์"</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"การตั้งค่า"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"WiFi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"โหมดใช้งานบนเครื่องบิน"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d ชั่วโมง"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"เปิดโหมดประหยัดแบตเตอรี่อยู่"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"ประสิทธิภาพการทำงานของอุปกรณ์ลดลง"</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"เปิดการตั้งค่าโหมดประหยัดแบตเตอรี่"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"เนื้อหาที่ซ่อน"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> จะเริ่มจับภาพทุกอย่างที่แสดงบนหน้าจอ"</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"ล้างทั้งหมด"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"เริ่มเลย"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"ไม่มีการแจ้งเตือน"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 850e6a1..b05dd4a 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Hindi sinusuportahan ang pagtsa-charge gamit ang USB."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Gamitin lang ang ibinigay na charger."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Mga Setting"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Simulan ang tagatipid ng baterya?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Magsimula"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Simulan ang tagatipid ng baterya"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Upang makatulong na patagalin ang baterya, babawasan ng Tagatipid ng baterya ang pagganap ng iyong device.\n\nIdi-disable ang tagatipid ng baterya kapag naka-plug in ang iyong device."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Mga Setting"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Airplane mode"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"Sa loob ng %d (na) oras"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Naka-on ang tagatipid ng baterya"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Binawasan ang pagganap ng device."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Buksan ang mga setting ng tagatipid ng baterya"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Nakatago ang mga content"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"Sisimulan ng i-capture ng <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ang lahat ng ipinapakita sa iyong screen."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"I-clear lahat"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Magsimula ngayon"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Walang mga notification"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 4884b57..110dd05 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB şarjı desteklenmiyor."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Yalnızca ürünle birlikte verilen şarj cihazını kullanın."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Ayarlar"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Pil tasarrufu başlatılsın mı?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Başlat"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Pil tasarrufunu başlat"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Pil tasarrufu, pil ömrünü iyileştirmeye yardımcı olmak için cihazınızın performansını düşürür.\n\nCihazınız fişe takıldığında Pil tasarrufu devre dışı bırakılır."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Ayarlar"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Kablosuz"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Uçak modu"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d saat süreyle"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Pil tasarrufu açık"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Cihazın performansı düşürüldü."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Pil tasarrufu ayarlarını aç"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"%%<xliff:g id="LEVEL">%d</xliff:g>"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"İçerik gizlendi"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>, ekranınızda görüntülenen her şeyi kaydetmeye başlayacak."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Tümü temizle"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Şimdi başla"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Bildirim yok"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 7ec651b..79193d8 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Заряджання через USB не підтримується."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Використовуйте лише зарядний пристрій, який постачається в комплекті."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Налаштування"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Увімкнути режим заощадження заряду акумулятора?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Почати"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Увімкнути режим заощадження заряду акумулятора"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Щоб подовжити роботу акумулятора, буде знижено продуктивність пристрою.\n\nРежим заощадження заряду акумулятора вимкнеться, коли пристрій буде підключено до мережі живлення."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Налаштування"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Режим польоту"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"Протягом %d год"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Режим заощадження заряду акумулятора ввімкнено"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Продуктивність пристрою знижено."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Відкрийте налаштування режиму заощадження заряду акумулятора"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Вміст сховано"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> отримає доступ до всіх даних, які відображаються на вашому екрані."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Очистити все"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Почати зараз"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Сповіщень немає"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 6ff5a63..0416be3 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"‏USB چارجنگ تعاون یافتہ نہیں ہے۔"</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"صرف فراہم کردہ چارجر استعمال کریں۔"</string>
     <string name="battery_low_why" msgid="4553600287639198111">"ترتیبات"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"بیٹری سیور شروع کریں؟"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"شروع کریں"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"بیٹری سیور شروع کریں"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"بیٹری کی میعاد کو بہتر بنانے میں مدد کرنے کیلئے، بیٹری سیور آپ کے آلے کی کارکردگی میں تخفیف کر دے گی۔\n\n آپ کا آلہ پلگ ان ہونے پر بیٹری سیور غیر فعال ہو جائے گی۔"</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"ترتیبات"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"ہوائی جہاز وضع"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"‏%d گھنٹوں کیلئے"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"بیٹری سیور آن ہے"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"آلہ کی کارکردگی کم ہوگئی ہے۔"</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"بیٹری سیور کی ترتیبات کھولیں"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"‎<xliff:g id="LEVEL">%d</xliff:g>%%‎"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"مواد مخفی ہیں"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> آپ کی اسکرین پر ڈسپلے ہونے والی ہر چیز کو کیپچر کرنا شروع کر دیگی۔"</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"سبھی کو صاف کریں"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ابھی شروع کریں"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"کوئی اطلاعات نہیں ہیں"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index d8b5699..62bcb12 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"USB orqali quvvat oldirish qo‘llab-quvvatlanmaydi."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Faqat qurilma bilan kelgan quvvatlash moslamasidan foydalaning."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Sozlamalar"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Quvvat tejash boshlansinmi?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Boshlash"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Quvvat tejashni boshlash"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Batareya quvvatini ko‘proq vaqtga yetkazish uchun Quvvat tejash funksiyasi qurilmangizning unumdorligini kamaytiradi.\n\nQurilmangiz quvvat olish uchun elektr ta’minotiga ulanganda Quvvat tejash funksiyasi o‘chiriladi."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Sozlamalar"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Parvoz rejimi"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d soat"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Quvvat tejash yoqilgan"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Qurilmaning unumdorligi kamaytirildi."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Quvvat tejash sozlamalarini ochish"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Kontent yashirildi"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ilovasi qurilma ekranidagi har qanday tasvirni ko‘rishni boshlaydi."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Barchasini tozalash"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Boshlash"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Bildirishnomalar yo‘q"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 360c087..ffc0621 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Sạc qua USB không được hỗ trợ."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Chỉ sử dụng bộ sạc được cung cấp."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Cài đặt"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Khởi động trình tiết kiệm pin?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Bắt đầu"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Khởi động trình tiết kiệm pin"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Để giúp tăng tuổi thọ pin, trình tiết kiệm pin sẽ giảm hiệu suất của thiết bị.\n\nTrình tiết kiệm pin sẽ tắt khi thiết bị của bạn được cắm vào nguồn điện."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Cài đặt"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Chế độ trên máy bay"</string>
@@ -150,7 +152,7 @@
     <string name="accessibility_tty_enabled" msgid="4613200365379426561">"Đã bật TeleTypewriter."</string>
     <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Chuông rung."</string>
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Chuông im lặng."</string>
-    <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Loại bỏ <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Xóa bỏ <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> đã bị loại bỏ."</string>
     <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Bắt đầu <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Đã loại bỏ thông báo."</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"Trong %d giờ"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Trình tiết kiệm pin đang bật"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Hiệu suất của thiết bị đã giảm."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Mở cài đặt trình tiết kiệm pin"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Nội dung bị ẩn"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sẽ bắt đầu chụp mọi thứ hiển thị trên màn hình."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Xóa tất cả"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Bắt đầu ngay"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Không có thông báo nào"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 939bb49..0556c29 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"不支持USB充电。"</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"仅限使用设备随附的充电器。"</string>
     <string name="battery_low_why" msgid="4553600287639198111">"设置"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"要开启节电助手吗?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"开启"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"开启节电助手"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"为了延长电池的续航时间,节电助手会减降设备的性能。\n\n设备接通电源后,节电助手会自动关闭。"</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"设置"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"WLAN"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"飞行模式"</string>
@@ -152,7 +154,7 @@
     <string name="accessibility_tty_enabled" msgid="4613200365379426561">"电传打字机已启用。"</string>
     <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"振铃器振动。"</string>
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"振铃器静音。"</string>
-    <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"关闭<xliff:g id="APP">%s</xliff:g>。"</string>
+    <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"移除<xliff:g id="APP">%s</xliff:g>。"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"已删除<xliff:g id="APP">%s</xliff:g>"</string>
     <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"正在启动<xliff:g id="APP">%s</xliff:g>。"</string>
     <string name="accessibility_notification_dismissed" msgid="854211387186306927">"已关闭通知。"</string>
@@ -288,8 +290,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d小时"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"节电助手已开启"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"设备性能已减降。"</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"打开节电助手设置"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"内容已隐藏"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>将开始截取您的屏幕上显示的所有内容。"</string>
@@ -297,4 +301,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"全部清除"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"立即开始"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"没有通知"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 832c507..21ee7fb 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"不支援 USB 充電功能。"</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"僅限使用裝置隨附的充電器。"</string>
     <string name="battery_low_why" msgid="4553600287639198111">"設定"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"啟動省電模式?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"開始"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"啟動省電模式"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"省電模式可延長電池使用時間,但會降低裝置的效能。\n\n裝置充電時,省電模式會自動停用。"</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"設定"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"飛行模式"</string>
@@ -288,8 +290,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d 小時"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"省電模式已開啟"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"裝置效能已降低。"</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"開啟省電設定"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"內容已隱藏"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 將開始擷取您的螢幕上顯示的內容。"</string>
@@ -297,4 +301,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"全部清除"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"立即開始"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"沒有通知"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 24ed6bf..9a29ed8 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"不支援 USB 充電功能。"</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"僅限使用裝置隨附的充電器。"</string>
     <string name="battery_low_why" msgid="4553600287639198111">"設定"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"啟動節約耗電量模式?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"啟動"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"啟動節約耗電量模式"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"節約耗電量模式有助於延長電池續航力,但會讓裝置的效能降低。\n\n裝置接上電源時,節約耗電量模式會自動停用。"</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"設定"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"飛行模式"</string>
@@ -288,8 +290,10 @@
     <item quantity="other" msgid="5408537517529822157">"%d 小時"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"節約耗電量模式已啟用"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"裝置效能已降低。"</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"開啟節約耗電量設定"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"內容已隱藏"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 將開始擷取您的螢幕上顯示的內容。"</string>
@@ -297,4 +301,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"全部清除"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"立即開始"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"沒有通知"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index d815668..2397502 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -39,10 +39,12 @@
     <string name="invalid_charger_title" msgid="3515740382572798460">"Ukushaja kwe-USB akusekelwe."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Sebenzisa kuphela ishaja enikeziwe."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Izilungiselelo"</string>
-    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Qala isilondolozi sebhethri?"</string>
-    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Qala"</string>
-    <string name="battery_saver_start_action" msgid="7245333922937402896">"Qala isilondolozi sebhethri"</string>
-    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Ukusiza ukuthuthukisa impilo yebhethri, Isilondolozi Sebhethri sizonciphisa ukusebenza kwedivayisi yakho.\n\nIsilondolozi Sebhethri sizokhutshazwa uma idivayisi yakho ixhunywa."</string>
+    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
+    <skip />
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Izilungiselelo"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"I-Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Imodi yendiza"</string>
@@ -286,8 +288,10 @@
     <item quantity="other" msgid="5408537517529822157">"Amahora angu-%d"</item>
   </plurals>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Isilondolozi sebhethri sivuliwe"</string>
-    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Ukusebenza kwedivayisi kwehlisiwe."</string>
-    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Vula izilungiselelo zesilondolozi sebhethri"</string>
+    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
+    <skip />
     <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Okuqukethwe kufihliwe"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> izoqala ukuthwebula yonke into eboniswa kusikrini sakho."</string>
@@ -295,4 +299,26 @@
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Sula konke"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Qala manje"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Azikho izaziso"</string>
+    <!-- no translation found for device_owned_footer (3802752663326030053) -->
+    <skip />
+    <!-- no translation found for vpn_footer (2388611096129106812) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
+    <skip />
+    <!-- no translation found for monitoring_title (169206259253048106) -->
+    <skip />
+    <!-- no translation found for open_app (4011771120339160755) -->
+    <skip />
+    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
+    <skip />
+    <!-- no translation found for monitoring_description_device_owned (7801926679066533391) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn (93140751707065515) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn (5397847778080663075) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_device_owned (696121105616356493) -->
+    <skip />
+    <!-- no translation found for monitoring_description_legacy_vpn_device_owned (649791650224064248) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values/arrays.xml b/packages/SystemUI/res/values/arrays.xml
index 6628f3b..630a48d 100644
--- a/packages/SystemUI/res/values/arrays.xml
+++ b/packages/SystemUI/res/values/arrays.xml
@@ -18,27 +18,6 @@
 */
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    
-    <array name="navbar_search_targets">
-        <item>@null</item>
-        <item>@drawable/ic_action_assist_generic</item>
-        <item>@null</item>
-        <item>@null</item>
-    </array>
-
-    <array name="navbar_search_target_descriptions">
-        <item>@null</item>
-        <item>@string/description_target_search</item>
-        <item>@null</item>
-        <item>@null</item>
-    </array>
-
-    <array name="navbar_search_direction_descriptions">
-        <item>@null</item>
-        <item>@string/description_direction_up</item>
-        <item>@null</item>
-        <item>@null</item>
-    </array>
 
     <!-- BatteryMeterView parameters -->
     <array name="batterymeter_color_levels">
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index a718f4f..1cdcc2b 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -44,6 +44,7 @@
     <color name="qs_tile_text">#B3FFFFFF</color><!-- 70% white -->
     <color name="qs_subhead">#99FFFFFF</color><!-- 60% white -->
     <color name="qs_detail_empty">#24B0BEC5</color><!-- 14% blue grey 200-->
+    <color name="qs_detail_transition">#66FFFFFF</color>
     <color name="data_usage_secondary">#99FFFFFF</color><!-- 60% white -->
     <color name="data_usage_graph_track">#33FFFFFF</color><!-- 20% white -->
     <color name="data_usage_graph_warning">#FFFFFFFF</color>
@@ -100,4 +101,6 @@
     <color name="notification_guts_title_color">#FFFFFFFF</color>
     <color name="notification_guts_text_color">#99FFFFFF</color>
     <color name="notification_guts_btn_color">#FFFFFFFF</color>
+
+    <color name="search_panel_card_color">#ffffff</color>
 </resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 230f4af..e05a897 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -162,16 +162,22 @@
     <!-- Doze: does this device support STATE_DOZE and STATE_DOZE_SUSPEND?  -->
     <bool name="doze_display_state_supported">false</bool>
 
-    <!-- Doze: should the significant motion sensor be used as a tease signal? -->
-    <bool name="doze_tease_on_significant_motion">false</bool>
+    <!-- Doze: should the significant motion sensor be used as a pulse signal? -->
+    <bool name="doze_pulse_on_significant_motion">false</bool>
 
-    <!-- Doze: maximum brightness to use when teasing -->
-    <integer name="doze_tease_brightness">80</integer>
+    <!-- Doze: maximum brightness to use when pulsing -->
+    <integer name="doze_pulse_brightness">40</integer>
+
+    <!-- Doze: number of pulses when doing multiple pulses in quick succession -->
+    <integer name="doze_multipulse_count">3</integer>
+
+    <!-- Doze: interval between pulses when following the notification light -->
+    <integer name="doze_notification_pulse_interval">30000</integer>
 
     <!-- Volume: time to delay dismissing the volume panel after a click is performed -->
     <integer name="volume_panel_dismiss_delay">200</integer>
 
-    <!-- Hotspot tile: number of days to show after feature is used. -->
-    <integer name="days_to_show_hotspot">30</integer>
+    <!-- Tiles with feature timeouts: number of days to show after feature is used. -->
+    <integer name="days_to_show_timeout_tiles">30</integer>
 </resources>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 127bdbe..11a8063 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -136,9 +136,14 @@
     <!-- Height of the status bar header bar when on Keyguard -->
     <dimen name="status_bar_header_height_keyguard">40dp</dimen>
 
+    <!-- Width for the notification panel and related windows -->
+    <dimen name="match_parent">-1px</dimen>
+    <dimen name="standard_notification_panel_width">416dp</dimen><!-- includes notification_side_padding on each side -->
+    <dimen name="notification_panel_width">@dimen/match_parent</dimen>
+
     <!-- Gravity for the notification panel -->
-    <!-- 0x37 = fill_horizontal|top -->
-    <integer name="notification_panel_layout_gravity">0x37</integer>
+    <integer name="standard_notification_panel_layout_gravity">0x31</integer><!-- top|center_horizontal -->
+    <integer name="notification_panel_layout_gravity">0x37</integer><!-- fill_horizontal|top -->
 
     <!-- Height of the carrier/wifi name label -->
     <dimen name="carrier_label_height">24dp</dimen>
@@ -269,9 +274,6 @@
     <!-- The height of the speed bump view. -->
     <dimen name="speed_bump_height">16dp</dimen>
 
-    <!-- Width of the zen mode interstitial dialog. -->
-    <dimen name="zen_mode_dialog_width">320dp</dimen>
-
     <!-- Lockscreen affordance drag distance for camera and phone. -->
     <dimen name="affordance_drag_distance">100dp</dimen>
 
@@ -381,7 +383,7 @@
     <dimen name="battery_level_padding_end">4dp</dimen>
 
     <!-- The top padding of the clear all button -->
-    <dimen name="clear_all_padding_top">4dp</dimen>
+    <dimen name="clear_all_padding_top">12dp</dimen>
 
     <!-- Largest size an avatar might need to be drawn in the user picker, status bar, or
          quick settings header -->
@@ -395,4 +397,25 @@
 
     <!-- Margin on the left side of the battery % when on Keyguard. -->
     <dimen name="header_battery_margin_keyguard">6dp</dimen>
+
+    <!-- Additional translation (downwards) for appearing notifications when going to the full shade
+         from Keyguard. -->
+    <dimen name="go_to_full_shade_appearing_translation">200dp</dimen>
+
+    <!-- The height of the search panel card. -->
+    <dimen name="search_panel_card_height">300dp</dimen>
+
+    <!-- The height of the scrim behind the search panel card. -->
+    <dimen name="search_panel_scrim_height">250dp</dimen>
+
+    <!-- How much from the bottom of the screen the card should peek in when activating the search
+         panel -->
+    <dimen name="search_card_peek_height">100dp</dimen>
+
+    <!-- How far the user needs to drag up to invoke search. -->
+    <dimen name="search_panel_threshold">150dp</dimen>
+
+    <!-- The width/height of the phone/camera/unlock icon on keyguard. -->
+    <dimen name="keyguard_affordance_height">56dp</dimen>
+    <dimen name="keyguard_affordance_width">56dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 085d2f9..83a9a81 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -86,16 +86,13 @@
     <string name="battery_low_why">Settings</string>
 
     <!-- Battery saver confirmation dialog title [CHAR LIMIT=NONE]-->
-    <string name="battery_saver_confirmation_title">Start battery saver?</string>
+    <string name="battery_saver_confirmation_title">Turn on battery saver?</string>
 
     <!-- Battery saver confirmation dialog ok text [CHAR LIMIT=40]-->
-    <string name="battery_saver_confirmation_ok">Start</string>
+    <string name="battery_saver_confirmation_ok">Turn on</string>
 
     <!-- Battery saver notification action [CHAR LIMIT=NONE]-->
-    <string name="battery_saver_start_action">Start battery saver</string>
-
-    <!-- Battery saver confirmation dialog text [CHAR LIMIT=NONE]-->
-    <string name="battery_saver_confirmation_text">To help improve battery life, Battery saver will reduce your device’s performance.\n\nBattery saver will be disabled when your device is plugged in.</string>
+    <string name="battery_saver_start_action">Turn on battery saver</string>
 
     <!-- Name of the button that links to the Settings app. [CHAR LIMIT=NONE] -->
     <string name="status_bar_settings_settings_button">Settings</string>
@@ -719,10 +716,10 @@
     <string name="battery_saver_notification_title">Battery saver is on</string>
 
     <!-- Battery saver notification text. [CHAR LIMIT=60] -->
-    <string name="battery_saver_notification_text">Device performance is reduced.</string>
+    <string name="battery_saver_notification_text">Reduces performance and background data</string>
 
     <!-- Battery saver notification action text. [CHAR LIMIT=60] -->
-    <string name="battery_saver_notification_action_text">Open battery saver settings</string>
+    <string name="battery_saver_notification_action_text">Turn off battery saver</string>
 
     <!-- Battery level for expanded quick settings [CHAR LIMIT=2] -->
     <string name="battery_level_template"><xliff:g id="level" example="45">%d</xliff:g>%%</string>
@@ -744,4 +741,38 @@
 
     <!-- Text which is shown in the notification shade when there are no notifications. [CHAR LIMIT=30] -->
     <string name="empty_shade_text">No notifications</string>
+
+    <!-- Footer device owned text [CHAR LIMIT=50] -->
+    <string name="device_owned_footer">Device may be monitored</string>
+
+    <!-- Footer vpn present text [CHAR LIMIT=50] -->
+    <string name="vpn_footer">Network may be monitored</string>
+
+    <!-- Monitoring dialog title for device owned devices [CHAR LIMIT=35] -->
+    <string name="monitoring_title_device_owned">Device monitoring</string>
+
+    <!-- Monitoring dialog title for normal devices  [CHAR LIMIT=35]-->
+    <string name="monitoring_title">Network monitoring</string>
+
+    <!-- Monitoring dialog open app button [CHAR LIMIT=30] -->
+    <string name="open_app">Open app</string>
+
+    <!-- Monitoring dialog disconnect vpn button [CHAR LIMIT=30] -->
+    <string name="disconnect_vpn">Disconnect VPN</string>
+
+    <!-- Monitoring dialog device owner body text [CHAR LIMIT=300] -->
+    <string name="monitoring_description_device_owned">This device is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\n\nYour administrator can monitor your network activity, including emails, apps and secure websites.\n\nFor more information, contact your administrator.</string>
+
+    <!-- Monitoring dialog non-legacy VPN text [CHAR LIMIT=300] -->
+    <string name="monitoring_description_vpn">You gave \"<xliff:g id="application">%1$s</xliff:g>\" permission to set up a VPN connection.\n\nThis app can monitor your network activity, including emails, apps and secure websites.</string>
+
+    <!-- Monitoring dialog legacy VPN text [CHAR LIMIT=300] -->
+    <string name="monitoring_description_legacy_vpn">You\'re connected to a VPN (\"<xliff:g id="application">%1$s</xliff:g>\").\n\nYour VPN service provider can monitor your network activity including emails, apps, and secure websites.</string>
+
+    <!-- Monitoring dialog non-legacy VPN with device owner text [CHAR LIMIT=300] -->
+    <string name="monitoring_description_vpn_device_owned">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>
+
+    <!-- Monitoring dialog legacy VPN with device owner text [CHAR LIMIT=300] -->
+    <string name="monitoring_description_legacy_vpn_device_owned">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>
+
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 61e6121..fc66730 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -254,16 +254,7 @@
         <item name="android:colorControlActivated">@color/system_accent_color</item>
     </style>
 
-    <style name="NotificationsQuickSettings">
-        <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_height">match_parent</item>
-    </style>
-
-    <style name="StatusBarHeader">
-        <item name="android:layout_width">match_parent</item>
-    </style>
-
-     <style name="QSBorderlessButton">
+    <style name="QSBorderlessButton">
         <item name="android:padding">12dp</item>
         <item name="android:background">@drawable/btn_borderless_rect</item>
         <item name="android:gravity">center</item>
@@ -280,4 +271,22 @@
         <item name="android:textStyle">italic</item>
         <item name="android:textColor">#60000000</item>
     </style>
+
+    <style name="SearchPanelCard">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">@dimen/search_panel_card_height</item>
+        <item name="android:layout_marginStart">8dp</item>
+        <item name="android:layout_marginEnd">8dp</item>
+        <item name="android:layout_gravity">bottom</item>
+    </style>
+
+    <style name="SearchPanelLogo">
+        <item name="android:layout_gravity">top|center_horizontal</item>
+    </style>
+
+    <style name="SearchPanelScrim">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">@dimen/search_panel_scrim_height</item>
+        <item name="android:layout_gravity">bottom</item>
+    </style>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
index 9650435..41d5984 100644
--- a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
@@ -25,7 +25,7 @@
     }
 
     void showRecents(boolean triggeredFromAltTab, View statusBarView);
-    void hideRecents(boolean triggeredFromAltTab);
+    void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
     void toggleRecents(Display display, int layoutDirection, View statusBarView);
     void preloadRecents();
     void cancelPreloadingRecents();
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
index ed03733..7d0ca14 100644
--- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -16,46 +16,41 @@
 
 package com.android.systemui;
 
-import android.animation.LayoutTransition;
-import android.app.ActivityManagerNative;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
 import android.app.ActivityOptions;
 import android.app.SearchManager;
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.media.AudioAttributes;
-import android.os.RemoteException;
-import android.os.ServiceManager;
+import android.os.AsyncTask;
+import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.Vibrator;
 import android.provider.Settings;
 import android.util.AttributeSet;
-import android.util.EventLog;
 import android.util.Log;
-import android.view.IWindowManager;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-import android.view.ViewTreeObserver.OnPreDrawListener;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
+import android.widget.ImageView;
 
-import com.android.internal.widget.multiwaveview.GlowPadView;
-import com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener;
 import com.android.systemui.statusbar.BaseStatusBar;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.StatusBarPanel;
-import com.android.systemui.statusbar.phone.KeyguardTouchDelegate;
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
 
-public class SearchPanelView extends FrameLayout implements
-        StatusBarPanel, ActivityOptions.OnAnimationStartedListener {
-    private static final int SEARCH_PANEL_HOLD_DURATION = 0;
-    static final String TAG = "SearchPanelView";
-    static final boolean DEBUG = PhoneStatusBar.DEBUG || false;
-    public static final boolean DEBUG_GESTURES = true;
+public class SearchPanelView extends FrameLayout implements StatusBarPanel {
+
+    private static final String TAG = "SearchPanelView";
     private static final String ASSIST_ICON_METADATA_NAME =
             "com.android.systemui.action_assist_icon";
 
@@ -67,10 +62,26 @@
     private final Context mContext;
     private BaseStatusBar mBar;
 
-    private boolean mShowing;
-    private View mSearchTargetsContainer;
-    private GlowPadView mGlowPadView;
-    private IWindowManager mWm;
+    private View mCard;
+    private ImageView mLogo;
+    private View mScrim;
+
+    private int mPeekHeight;
+    private int mThreshold;
+    private boolean mHorizontal;
+    private final Interpolator mLinearOutSlowInInterpolator;
+    private final Interpolator mFastOutLinearInInterpolator;
+
+    private boolean mAnimatingIn;
+    private boolean mAnimatingOut;
+    private boolean mDragging;
+    private boolean mDraggedFarEnough;
+    private float mStartTouch;
+    private float mStartDrag;
+
+    private ObjectAnimator mEnterAnimator;
+
+    private boolean mStartExitAfterAnimatingIn;
 
     public SearchPanelView(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
@@ -79,7 +90,12 @@
     public SearchPanelView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         mContext = context;
-        mWm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
+        mPeekHeight = context.getResources().getDimensionPixelSize(R.dimen.search_card_peek_height);
+        mThreshold = context.getResources().getDimensionPixelSize(R.dimen.search_panel_threshold);
+        mLinearOutSlowInInterpolator =
+                AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in);
+        mFastOutLinearInInterpolator =
+                AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_linear_in);
     }
 
     private void startAssistActivity() {
@@ -87,92 +103,34 @@
 
         // Close Recent Apps if needed
         mBar.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL);
-        boolean isKeyguardShowing = false;
+
+        final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
+                .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
+        if (intent == null) return;
+
         try {
-            isKeyguardShowing = mWm.isKeyguardLocked();
-        } catch (RemoteException e) {
-
+            final ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
+                    R.anim.search_launch_enter, R.anim.search_launch_exit);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            AsyncTask.execute(new Runnable() {
+                @Override
+                public void run() {
+                    mContext.startActivityAsUser(intent, opts.toBundle(),
+                            new UserHandle(UserHandle.USER_CURRENT));
+                }
+            });
+        } catch (ActivityNotFoundException e) {
+            Log.w(TAG, "Activity not found for " + intent.getAction());
         }
-
-        if (isKeyguardShowing) {
-            // Have keyguard show the bouncer and launch the activity if the user succeeds.
-            KeyguardTouchDelegate.getInstance(getContext()).showAssistant();
-            onAnimationStarted();
-        } else {
-            // Otherwise, keyguard isn't showing so launch it from here.
-            Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
-                    .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
-            if (intent == null) return;
-
-            try {
-                ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
-            } catch (RemoteException e) {
-                // too bad, so sad...
-            }
-
-            try {
-                ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
-                        R.anim.search_launch_enter, R.anim.search_launch_exit,
-                        getHandler(), this);
-                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                mContext.startActivityAsUser(intent, opts.toBundle(),
-                        new UserHandle(UserHandle.USER_CURRENT));
-            } catch (ActivityNotFoundException e) {
-                Log.w(TAG, "Activity not found for " + intent.getAction());
-                onAnimationStarted();
-            }
-        }
-    }
-
-    class GlowPadTriggerListener implements GlowPadView.OnTriggerListener {
-        boolean mWaitingForLaunch;
-
-        public void onGrabbed(View v, int handle) {
-        }
-
-        public void onReleased(View v, int handle) {
-        }
-
-        public void onGrabbedStateChange(View v, int handle) {
-            if (!mWaitingForLaunch && OnTriggerListener.NO_HANDLE == handle) {
-                mBar.hideSearchPanel();
-            }
-        }
-
-        public void onTrigger(View v, final int target) {
-            final int resId = mGlowPadView.getResourceIdForTarget(target);
-            switch (resId) {
-                case R.drawable.ic_action_assist_generic:
-                    mWaitingForLaunch = true;
-                    startAssistActivity();
-                    vibrate();
-                    break;
-            }
-        }
-
-        public void onFinishFinalAnimation() {
-        }
-    }
-    final GlowPadTriggerListener mGlowPadViewListener = new GlowPadTriggerListener();
-
-    @Override
-    public void onAnimationStarted() {
-        postDelayed(new Runnable() {
-            public void run() {
-                mGlowPadViewListener.mWaitingForLaunch = false;
-                mBar.hideSearchPanel();
-            }
-        }, SEARCH_PANEL_HOLD_DURATION);
     }
 
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
         mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        mSearchTargetsContainer = findViewById(R.id.search_panel_container);
-        // TODO: fetch views
-        mGlowPadView = (GlowPadView) findViewById(R.id.glow_pad_view);
-        mGlowPadView.setOnTriggerListener(mGlowPadViewListener);
+        mCard = findViewById(R.id.search_panel_card);
+        mLogo = (ImageView) findViewById(R.id.search_logo);
+        mScrim = findViewById(R.id.search_panel_scrim);
     }
 
     private void maybeSwapSearchIcon() {
@@ -180,12 +138,36 @@
                 .getAssistIntent(mContext, false, UserHandle.USER_CURRENT);
         if (intent != null) {
             ComponentName component = intent.getComponent();
-            if (component == null || !mGlowPadView.replaceTargetDrawablesIfPresent(component,
-                    ASSIST_ICON_METADATA_NAME,
-                    R.drawable.ic_action_assist_generic)) {
-                if (DEBUG) Log.v(TAG, "Couldn't grab icon for component " + component);
+            replaceDrawable(mLogo, component, ASSIST_ICON_METADATA_NAME);
+        } else {
+            mLogo.setImageDrawable(null);
+        }
+    }
+
+    public void replaceDrawable(ImageView v, ComponentName component, String name) {
+        if (component != null) {
+            try {
+                PackageManager packageManager = mContext.getPackageManager();
+                // Look for the search icon specified in the activity meta-data
+                Bundle metaData = packageManager.getActivityInfo(
+                        component, PackageManager.GET_META_DATA).metaData;
+                if (metaData != null) {
+                    int iconResId = metaData.getInt(name);
+                    if (iconResId != 0) {
+                        Resources res = packageManager.getResourcesForActivity(component);
+                        v.setImageDrawable(res.getDrawable(iconResId));
+                        return;
+                    }
+                }
+            } catch (PackageManager.NameNotFoundException e) {
+                Log.w(TAG, "Failed to swap drawable; "
+                        + component.flattenToShortString() + " not found", e);
+            } catch (Resources.NotFoundException nfe) {
+                Log.w(TAG, "Failed to swap drawable from "
+                        + component.flattenToShortString(), nfe);
             }
         }
+        v.setImageDrawable(null);
     }
 
     private boolean pointInside(int x, int y, View v) {
@@ -197,17 +179,9 @@
     }
 
     public boolean isInContentArea(int x, int y) {
-        return pointInside(x, y, mSearchTargetsContainer);
+        return pointInside(x, y, mCard);
     }
 
-    private final OnPreDrawListener mPreDrawListener = new ViewTreeObserver.OnPreDrawListener() {
-        public boolean onPreDraw() {
-            getViewTreeObserver().removeOnPreDrawListener(this);
-            mGlowPadView.resumeAnimations();
-            return false;
-        }
-    };
-
     private void vibrate() {
         Context context = getContext();
         if (Settings.System.getIntForUser(context.getContentResolver(),
@@ -220,49 +194,108 @@
     }
 
     public void show(final boolean show, boolean animate) {
-        if (!show) {
-            final LayoutTransition transitioner = animate ? createLayoutTransitioner() : null;
-            ((ViewGroup) mSearchTargetsContainer).setLayoutTransition(transitioner);
-        }
-        mShowing = show;
         if (show) {
             maybeSwapSearchIcon();
             if (getVisibility() != View.VISIBLE) {
                 setVisibility(View.VISIBLE);
-                // Don't start the animation until we've created the layer, which is done
-                // right before we are drawn
-                mGlowPadView.suspendAnimations();
-                mGlowPadView.ping();
-                getViewTreeObserver().addOnPreDrawListener(mPreDrawListener);
                 vibrate();
+                mCard.setAlpha(1f);
+                if (animate) {
+                    startEnterAnimation();
+                } else {
+                    mScrim.setAlpha(1f);
+                    if (mHorizontal) {
+                        mCard.setX(getWidth() - mPeekHeight);
+                    } else {
+                        mCard.setY(getHeight() - mPeekHeight);
+                    }
+                }
             }
             setFocusable(true);
             setFocusableInTouchMode(true);
             requestFocus();
         } else {
-            setVisibility(View.INVISIBLE);
+            if (animate) {
+                startAbortAnimation();
+            } else {
+                setVisibility(View.INVISIBLE);
+            }
         }
     }
 
+    private void startEnterAnimation() {
+        if (mHorizontal) {
+            mCard.setX(getWidth());
+        } else {
+            mCard.setY(getHeight());
+        }
+        mAnimatingIn = true;
+        mCard.animate().cancel();
+        mEnterAnimator = ObjectAnimator.ofFloat(mCard, mHorizontal ? View.X : View.Y,
+                mHorizontal ? mCard.getX() : mCard.getY(),
+                mHorizontal ? getWidth() - mPeekHeight : getHeight() - mPeekHeight);
+        mEnterAnimator.setDuration(300);
+        mEnterAnimator.setStartDelay(50);
+        mEnterAnimator.setInterpolator(mLinearOutSlowInInterpolator);
+        mEnterAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mEnterAnimator = null;
+                mAnimatingIn = false;
+                if (mStartExitAfterAnimatingIn) {
+                    startExitAnimation();
+                }
+            }
+        });
+        mEnterAnimator.start();
+        mScrim.setAlpha(0f);
+        mScrim.animate()
+                .alpha(1f)
+                .setDuration(300)
+                .setStartDelay(50)
+                .setInterpolator(PhoneStatusBar.ALPHA_IN)
+                .start();
+
+    }
+
+    private void startAbortAnimation() {
+        mCard.animate().cancel();
+        mAnimatingOut = true;
+        if (mHorizontal) {
+            mCard.animate().x(getWidth());
+        } else {
+            mCard.animate().y(getHeight());
+        }
+        mCard.animate()
+                .setDuration(150)
+                .setInterpolator(mFastOutLinearInInterpolator)
+                .withEndAction(new Runnable() {
+                    @Override
+                    public void run() {
+                        mAnimatingOut = false;
+                        setVisibility(View.INVISIBLE);
+                    }
+                });
+        mScrim.animate()
+                .alpha(0f)
+                .setDuration(150)
+                .setStartDelay(0)
+                .setInterpolator(PhoneStatusBar.ALPHA_OUT);
+    }
+
     public void hide(boolean animate) {
         if (mBar != null) {
             // This will indirectly cause show(false, ...) to get called
             mBar.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
         } else {
-            setVisibility(View.INVISIBLE);
+            if (animate) {
+                startAbortAnimation();
+            } else {
+                setVisibility(View.INVISIBLE);
+            }
         }
     }
 
-    /**
-     * We need to be aligned at the bottom.  LinearLayout can't do this, so instead,
-     * let LinearLayout do all the hard work, and then shift everything down to the bottom.
-     */
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        super.onLayout(changed, l, t, r, b);
-        // setPanelHeight(mSearchTargetsContainer.getHeight());
-    }
-
     @Override
     public boolean dispatchHoverEvent(MotionEvent event) {
         // Ignore hover events outside of this panel bounds since such events
@@ -281,34 +314,113 @@
      * when the animation is done.
      */
     public boolean isShowing() {
-        return mShowing;
+        return getVisibility() == View.VISIBLE && !mAnimatingOut;
     }
 
     public void setBar(BaseStatusBar bar) {
         mBar = bar;
     }
 
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        if (DEBUG_GESTURES) {
-            if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
-                EventLog.writeEvent(EventLogTags.SYSUI_SEARCHPANEL_TOUCH,
-                        event.getActionMasked(), (int) event.getX(), (int) event.getY());
-            }
-        }
-        return super.onTouchEvent(event);
-    }
-
-    private LayoutTransition createLayoutTransitioner() {
-        LayoutTransition transitioner = new LayoutTransition();
-        transitioner.setDuration(200);
-        transitioner.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0);
-        transitioner.setAnimator(LayoutTransition.DISAPPEARING, null);
-        return transitioner;
-    }
-
     public boolean isAssistantAvailable() {
         return ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
                 .getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
     }
+
+    private float rubberband(float diff) {
+        return Math.signum(diff) * (float) Math.pow(Math.abs(diff), 0.8f);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        int action = event.getActionMasked();
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                mStartTouch = mHorizontal ? event.getX() : event.getY();
+                mDragging = false;
+                mDraggedFarEnough = false;
+                mStartExitAfterAnimatingIn = false;
+                break;
+            case MotionEvent.ACTION_MOVE:
+                float currentTouch = mHorizontal ? event.getX() : event.getY();
+                if (getVisibility() == View.VISIBLE && !mDragging &&
+                        (!mAnimatingIn || Math.abs(mStartTouch - currentTouch) > mThreshold)) {
+                    mStartDrag = currentTouch;
+                    mDragging = true;
+                }
+                if (!mDraggedFarEnough && Math.abs(mStartTouch - currentTouch) > mThreshold) {
+                    mDraggedFarEnough = true;
+                }
+                if (mDragging) {
+                    if (!mAnimatingIn && !mAnimatingOut) {
+                        if (Math.abs(currentTouch - mStartDrag) > mThreshold) {
+                            startExitAnimation();
+                        } else {
+                            if (mHorizontal) {
+                                mCard.setX(getWidth() - mPeekHeight + rubberband(
+                                        currentTouch - mStartDrag));
+                            } else {
+                                mCard.setY(getHeight() - mPeekHeight + rubberband(
+                                        currentTouch - mStartDrag));
+                            }
+                        }
+                    } else if (mAnimatingIn ) {
+                        float diff = rubberband(currentTouch - mStartDrag);
+                        PropertyValuesHolder[] values = mEnterAnimator.getValues();
+                        values[0].setFloatValues(
+                                mHorizontal ? getWidth() + diff : getHeight() + diff,
+                                mHorizontal
+                                        ? getWidth() - mPeekHeight + diff
+                                        : getHeight() - mPeekHeight + diff);
+                        mEnterAnimator.setCurrentPlayTime(mEnterAnimator.getCurrentPlayTime());
+                    }
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                if (mDraggedFarEnough) {
+                    if (mAnimatingIn) {
+                        mStartExitAfterAnimatingIn = true;
+                    } else {
+                        startExitAnimation();
+                    }
+                } else {
+                    startAbortAnimation();
+                }
+                break;
+        }
+        return true;
+    }
+
+    private void startExitAnimation() {
+        if (mAnimatingOut || getVisibility() != View.VISIBLE) {
+            return;
+        }
+        if (mEnterAnimator != null) {
+            mEnterAnimator.cancel();
+        }
+        mAnimatingOut = true;
+        startAssistActivity();
+        vibrate();
+        mCard.animate()
+                .alpha(0f)
+                .withLayer()
+                .setDuration(250)
+                .setInterpolator(PhoneStatusBar.ALPHA_OUT)
+                .withEndAction(new Runnable() {
+                    @Override
+                    public void run() {
+                        mAnimatingOut = false;
+                        setVisibility(View.INVISIBLE);
+                    }
+                });
+        mScrim.animate()
+                .alpha(0f)
+                .setDuration(250)
+                .setStartDelay(0)
+                .setInterpolator(PhoneStatusBar.ALPHA_OUT);
+    }
+
+    public void setHorizontal(boolean horizontal) {
+        mHorizontal = horizontal;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 6c30c89..a18b0c0 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -384,10 +384,19 @@
         }
 
         if (!mDragging) {
-            // We are not doing anything, make sure the long press callback
-            // is not still ticking like a bomb waiting to go off.
-            removeLongPressCallback();
-            return false;
+            if (mCallback.getChildAtPosition(ev) != null) {
+
+                // We are dragging directly over a card, make sure that we also catch the gesture
+                // even if nobody else wants the touch event.
+                onInterceptTouchEvent(ev);
+                return true;
+            } else {
+
+                // We are not doing anything, make sure the long press callback
+                // is not still ticking like a bomb waiting to go off.
+                removeLongPressCallback();
+                return false;
+            }
         }
 
         mVelocityTracker.addMovement(ev);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 13c15f5..943a294 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -19,6 +19,8 @@
 import static android.os.PowerManager.BRIGHTNESS_OFF;
 import static android.os.PowerManager.BRIGHTNESS_ON;
 
+import android.app.AlarmManager;
+import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -42,12 +44,16 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.Date;
 
 public class DozeService extends DreamService {
     private static final String TAG = "DozeService";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
-    private static final String TEASE_ACTION = "com.android.systemui.doze.tease";
+    private static final String ACTION_BASE = "com.android.systemui.doze";
+    private static final String PULSE_ACTION = ACTION_BASE + ".pulse";
+    private static final String NOTIFICATION_PULSE_ACTION = ACTION_BASE + ".notification_pulse";
+    private static final String EXTRA_PULSES = "pulses";
 
     private final String mTag = String.format(TAG + ".%08x", hashCode());
     private final Context mContext = this;
@@ -58,13 +64,18 @@
     private Sensor mSigMotionSensor;
     private PowerManager mPowerManager;
     private PowerManager.WakeLock mWakeLock;
+    private AlarmManager mAlarmManager;
     private int mMaxBrightness;
     private boolean mDreaming;
-    private boolean mTeaseReceiverRegistered;
+    private boolean mBroadcastReceiverRegistered;
     private boolean mSigMotionConfigured;
     private boolean mSigMotionEnabled;
     private boolean mDisplayStateSupported;
     private int mDisplayStateWhenOn;
+    private boolean mNotificationLightOn;
+    private PendingIntent mNotificationPulseIntent;
+    private int mMultipulseCount;
+    private int mNotificationPulseInterval;
 
     public DozeService() {
         if (DEBUG) Log.d(mTag, "new DozeService()");
@@ -75,12 +86,15 @@
     protected void dumpOnHandler(FileDescriptor fd, PrintWriter pw, String[] args) {
         super.dumpOnHandler(fd, pw, args);
         pw.print("  mDreaming: "); pw.println(mDreaming);
-        pw.print("  mTeaseReceiverRegistered: "); pw.println(mTeaseReceiverRegistered);
+        pw.print("  mBroadcastReceiverRegistered: "); pw.println(mBroadcastReceiverRegistered);
         pw.print("  mSigMotionSensor: "); pw.println(mSigMotionSensor);
         pw.print("  mSigMotionConfigured: "); pw.println(mSigMotionConfigured);
         pw.print("  mSigMotionEnabled: "); pw.println(mSigMotionEnabled);
         pw.print("  mMaxBrightness: "); pw.println(mMaxBrightness);
         pw.print("  mDisplayStateSupported: "); pw.println(mDisplayStateSupported);
+        pw.print("  mNotificationLightOn: "); pw.println(mNotificationLightOn);
+        pw.print("  mMultipulseCount: "); pw.println(mMultipulseCount);
+        pw.print("  mNotificationPulseInterval: "); pw.println(mNotificationPulseInterval);
     }
 
     @Override
@@ -99,14 +113,21 @@
         mSigMotionSensor = mSensors.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION);
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, mTag);
+        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
         final Resources res = mContext.getResources();
-        mSigMotionConfigured = SystemProperties.getBoolean("doze.tease.sigmotion",
-                res.getBoolean(R.bool.doze_tease_on_significant_motion));
+        mSigMotionConfigured = SystemProperties.getBoolean("doze.pulse.sigmotion",
+                res.getBoolean(R.bool.doze_pulse_on_significant_motion));
         mDisplayStateSupported = SystemProperties.getBoolean("doze.display.supported",
                 res.getBoolean(R.bool.doze_display_state_supported));
-        mMaxBrightness = MathUtils.constrain(res.getInteger(R.integer.doze_tease_brightness),
+        mMaxBrightness = MathUtils.constrain(res.getInteger(R.integer.doze_pulse_brightness),
                 BRIGHTNESS_OFF, BRIGHTNESS_ON);
-
+        mNotificationPulseIntent = PendingIntent.getBroadcast(mContext, 0,
+                new Intent(NOTIFICATION_PULSE_ACTION).setPackage(getPackageName()),
+                PendingIntent.FLAG_CANCEL_CURRENT);
+        mMultipulseCount = SystemProperties.getInt("doze.multipulses",
+                res.getInteger(R.integer.doze_multipulse_count));
+        mNotificationPulseInterval = SystemProperties.getInt("doze.notification.pulse",
+                res.getInteger(R.integer.doze_notification_pulse_interval));
         mDisplayStateWhenOn = mDisplayStateSupported ? Display.STATE_DOZE : Display.STATE_ON;
         setDozeScreenState(mDisplayStateWhenOn);
     }
@@ -122,7 +143,7 @@
         super.onDreamingStarted();
         if (DEBUG) Log.d(mTag, "onDreamingStarted canDoze=" + canDoze());
         mDreaming = true;
-        listenForTeaseSignals(true);
+        listenForPulseSignals(true);
         requestDoze();
     }
 
@@ -160,7 +181,7 @@
         if (mWakeLock.isHeld()) {
             mWakeLock.release();
         }
-        listenForTeaseSignals(false);
+        listenForPulseSignals(false);
         stopDozing();
         dozingStopped();
     }
@@ -187,9 +208,17 @@
         }
     }
 
-    private void requestTease() {
+    private void requestMultipulse() {
+        requestPulse(mMultipulseCount);
+    }
+
+    private void requestPulse() {
+        requestPulse(1);
+    }
+
+    private void requestPulse(int pulses) {
         if (mHost != null) {
-            mHost.requestTease(this);
+            mHost.requestPulse(pulses, this);
         }
     }
 
@@ -199,10 +228,10 @@
         }
     }
 
-    private void listenForTeaseSignals(boolean listen) {
-        if (DEBUG) Log.d(mTag, "listenForTeaseSignals: " + listen);
+    private void listenForPulseSignals(boolean listen) {
+        if (DEBUG) Log.d(mTag, "listenForPulseSignals: " + listen);
         listenForSignificantMotion(listen);
-        listenForBroadcast(listen);
+        listenForBroadcasts(listen);
         listenForNotifications(listen);
     }
 
@@ -216,15 +245,17 @@
         }
     }
 
-    private void listenForBroadcast(boolean listen) {
+    private void listenForBroadcasts(boolean listen) {
         if (listen) {
-            mContext.registerReceiver(mTeaseReceiver, new IntentFilter(TEASE_ACTION));
-            mTeaseReceiverRegistered = true;
+            final IntentFilter filter = new IntentFilter(PULSE_ACTION);
+            filter.addAction(NOTIFICATION_PULSE_ACTION);
+            mContext.registerReceiver(mBroadcastReceiver, filter);
+            mBroadcastReceiverRegistered = true;
         } else {
-            if (mTeaseReceiverRegistered) {
-                mContext.unregisterReceiver(mTeaseReceiver);
+            if (mBroadcastReceiverRegistered) {
+                mContext.unregisterReceiver(mBroadcastReceiver);
             }
-            mTeaseReceiverRegistered = false;
+            mBroadcastReceiverRegistered = false;
         }
     }
 
@@ -237,6 +268,15 @@
         }
     }
 
+    private void rescheduleNotificationPulse() {
+        mAlarmManager.cancel(mNotificationPulseIntent);
+        if (mNotificationLightOn) {
+            final long time = System.currentTimeMillis() + mNotificationPulseInterval;
+            if (DEBUG) Log.d(TAG, "Scheduling pulse for " + new Date(time));
+            mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, time, mNotificationPulseIntent);
+        }
+    }
+
     private static String triggerEventToString(TriggerEvent event) {
         if (event == null) return null;
         final StringBuilder sb = new StringBuilder("TriggerEvent[")
@@ -269,16 +309,23 @@
                     v.vibrate(1000);
                 }
             }
-            requestTease();
+            requestPulse();
             listenForSignificantMotion(true);  // reregister, this sensor only fires once
         }
     };
 
-    private final BroadcastReceiver mTeaseReceiver = new BroadcastReceiver() {
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (DEBUG) Log.d(mTag, "Received tease intent");
-            requestTease();
+            if (PULSE_ACTION.equals(intent.getAction())) {
+                if (DEBUG) Log.d(mTag, "Received pulse intent");
+                requestPulse(intent.getIntExtra(EXTRA_PULSES, mMultipulseCount));
+            }
+            if (NOTIFICATION_PULSE_ACTION.equals(intent.getAction())) {
+                if (DEBUG) Log.d(mTag, "Received notification pulse intent");
+                requestPulse();
+                rescheduleNotificationPulse();
+            }
         }
     };
 
@@ -288,10 +335,19 @@
             if (DEBUG) Log.d(mTag, "onNewNotifications");
             // noop for now
         }
+
         @Override
         public void onBuzzBeepBlinked() {
             if (DEBUG) Log.d(mTag, "onBuzzBeepBlinked");
-            requestTease();
+            requestMultipulse();
+        }
+
+        @Override
+        public void onNotificationLight(boolean on) {
+            if (DEBUG) Log.d(mTag, "onNotificationLight on=" + on);
+            if (mNotificationLightOn == on) return;
+            mNotificationLightOn = on;
+            rescheduleNotificationPulse();
         }
     };
 
@@ -299,12 +355,13 @@
         void addCallback(Callback callback);
         void removeCallback(Callback callback);
         void requestDoze(DozeService dozeService);
-        void requestTease(DozeService dozeService);
+        void requestPulse(int pulses, DozeService dozeService);
         void dozingStopped(DozeService dozeService);
 
         public interface Callback {
             void onNewNotifications();
             void onBuzzBeepBlinked();
+            void onNotificationLight(boolean on);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java
index 2943494..79fadbd 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java
@@ -48,7 +48,6 @@
     private int mBucket;
     private long mScreenOffTime;
     private boolean mSaver;
-    private int mSaverTriggerLevel;
 
     private AlertDialog mInvalidChargerDialog;
     private AlertDialog mLowBatteryDialog;
@@ -222,9 +221,4 @@
     public void showSaverMode(boolean mode) {
         mSaver = mode;
     }
-
-    @Override
-    public void setSaverTrigger(int level) {
-        mSaverTriggerLevel = level;
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 186b570..dd923e3 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.power;
 
-import android.app.AlertDialog;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -25,9 +24,10 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
+import android.content.DialogInterface.OnDismissListener;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.media.AudioManager;
+import android.media.AudioAttributes;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Handler;
@@ -35,11 +35,10 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Slog;
-import android.view.ContextThemeWrapper;
 import android.view.View;
-import android.view.WindowManager;
 
 import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
 
 import java.io.PrintWriter;
 
@@ -66,9 +65,14 @@
     private static final String ACTION_SHOW_FALLBACK_CHARGER = "PNW.chargerFallback";
     private static final String ACTION_SHOW_BATTERY_SETTINGS = "PNW.batterySettings";
     private static final String ACTION_START_SAVER = "PNW.startSaver";
+    private static final String ACTION_STOP_SAVER = "PNW.stopSaver";
+
+    private static final AudioAttributes AUDIO_ATTRIBUTES = new AudioAttributes.Builder()
+            .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+            .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
+            .build();
 
     private final Context mContext;
-    private final Context mLightContext;
     private final NotificationManager mNoMan;
     private final Handler mHandler = new Handler();
     private final PowerDialogWarnings mFallbackDialogs;
@@ -84,15 +88,13 @@
     private long mBucketDroppedNegativeTimeMs;
 
     private boolean mSaver;
-    private int mSaverTriggerLevel;
     private boolean mWarning;
     private boolean mPlaySound;
     private boolean mInvalidCharger;
+    private SystemUIDialog mSaverConfirmation;
 
     public PowerNotificationWarnings(Context context) {
         mContext = context;
-        mLightContext = new ContextThemeWrapper(mContext,
-                android.R.style.Theme_DeviceDefault_Light);
         mNoMan = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
         mFallbackDialogs = new PowerDialogWarnings(context);
         mReceiver.init();
@@ -105,6 +107,7 @@
         pw.print("mPlaySound="); pw.println(mPlaySound);
         pw.print("mInvalidCharger="); pw.println(mInvalidCharger);
         pw.print("mShowing="); pw.println(SHOWING_STRINGS[mShowing]);
+        pw.print("mSaverConfirmation="); pw.println(mSaverConfirmation != null ? "not null" : null);
     }
 
     @Override
@@ -123,12 +126,9 @@
     @Override
     public void showSaverMode(boolean mode) {
         mSaver = mode;
-        updateNotification();
-    }
-
-    @Override
-    public void setSaverTrigger(int level) {
-        mSaverTriggerLevel = level;
+        if (mSaver && mSaverConfirmation != null) {
+            mSaverConfirmation.dismiss();
+        }
         updateNotification();
     }
 
@@ -180,6 +180,7 @@
                 .setContentTitle(mContext.getString(R.string.battery_low_title))
                 .setContentText(mContext.getString(textRes, mBatteryLevel))
                 .setOngoing(true)
+                .setOnlyAlertOnce(true)
                 .setPriority(Notification.PRIORITY_MAX)
                 .setCategory(Notification.CATEGORY_SYSTEM)
                 .setVisibility(Notification.VISIBILITY_PUBLIC)
@@ -187,10 +188,12 @@
         if (hasBatterySettings()) {
             nb.setContentIntent(pendingBroadcast(ACTION_SHOW_BATTERY_SETTINGS));
         }
-        if (!mSaver && mSaverTriggerLevel <= 0) {
-            nb.addAction(R.drawable.ic_power_saver,
+        if (!mSaver) {
+            nb.addAction(0,
                     mContext.getString(R.string.battery_saver_start_action),
                     pendingBroadcast(ACTION_START_SAVER));
+        } else {
+            addStopSaverAction(nb);
         }
         if (mPlaySound) {
             attachLowBatterySound(nb);
@@ -208,19 +211,28 @@
                 .setContentTitle(mContext.getString(R.string.battery_saver_notification_title))
                 .setContentText(mContext.getString(R.string.battery_saver_notification_text))
                 .setOngoing(true)
-                .setWhen(0)
                 .setShowWhen(false)
                 .setCategory(Notification.CATEGORY_SYSTEM)
                 .setVisibility(Notification.VISIBILITY_PUBLIC);
+        addStopSaverAction(nb);
         if (hasSaverSettings()) {
-            nb.addAction(0,
-                    mContext.getString(R.string.battery_saver_notification_action_text),
-                    pendingActivity(mOpenSaverSettings));
             nb.setContentIntent(pendingActivity(mOpenSaverSettings));
         }
         mNoMan.notifyAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, nb.build(), UserHandle.CURRENT);
     }
 
+    private void addStopSaverAction(Notification.Builder nb) {
+        nb.addAction(0,
+                mContext.getString(R.string.battery_saver_notification_action_text),
+                pendingBroadcast(ACTION_STOP_SAVER));
+    }
+
+    private void dismissSaverNotification() {
+        if (mSaver) Slog.i(TAG, "dismissing saver notification");
+        mSaver = false;
+        updateNotification();
+    }
+
     private PendingIntent pendingActivity(Intent intent) {
         return PendingIntent.getActivityAsUser(mContext,
                 0, intent, 0, null, UserHandle.CURRENT);
@@ -307,8 +319,8 @@
             if (soundPath != null) {
                 final Uri soundUri = Uri.parse("file://" + soundPath);
                 if (soundUri != null) {
-                    b.setSound(soundUri, AudioManager.STREAM_SYSTEM);
-                    Slog.d(TAG, "playing sound " + soundUri);
+                    b.setSound(soundUri, AUDIO_ATTRIBUTES);
+                    if (DEBUG) Slog.d(TAG, "playing sound " + soundUri);
                 }
             }
         }
@@ -333,17 +345,21 @@
     }
 
     private void showStartSaverConfirmation() {
-        final AlertDialog d = new AlertDialog.Builder(mLightContext)
-                .setTitle(R.string.battery_saver_confirmation_title)
-                .setMessage(R.string.battery_saver_confirmation_text)
-                .setNegativeButton(android.R.string.cancel, null)
-                .setPositiveButton(R.string.battery_saver_confirmation_ok, mStartSaverMode)
-                .create();
-
-        d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
-        d.getWindow().getAttributes().privateFlags |=
-                WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+        if (mSaverConfirmation != null) return;
+        final SystemUIDialog d = new SystemUIDialog(mContext);
+        d.setTitle(R.string.battery_saver_confirmation_title);
+        d.setMessage(com.android.internal.R.string.battery_saver_description);
+        d.setNegativeButton(android.R.string.cancel, null);
+        d.setPositiveButton(R.string.battery_saver_confirmation_ok, mStartSaverMode);
+        d.setShowForAllUsers(true);
+        d.setOnDismissListener(new OnDismissListener() {
+            @Override
+            public void onDismiss(DialogInterface dialog) {
+                mSaverConfirmation = null;
+            }
+        });
         d.show();
+        mSaverConfirmation = d;
     }
 
     private void setSaverSetting(boolean mode) {
@@ -359,6 +375,7 @@
             filter.addAction(ACTION_SHOW_FALLBACK_CHARGER);
             filter.addAction(ACTION_SHOW_BATTERY_SETTINGS);
             filter.addAction(ACTION_START_SAVER);
+            filter.addAction(ACTION_STOP_SAVER);
             mContext.registerReceiver(this, filter, null, mHandler);
         }
 
@@ -378,6 +395,10 @@
             } else if (action.equals(ACTION_START_SAVER)) {
                 dismissLowBatteryNotification();
                 showStartSaverConfirmation();
+            } else if (action.equals(ACTION_STOP_SAVER)) {
+                dismissSaverNotification();
+                dismissLowBatteryNotification();
+                setSaverSetting(false);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 1bb7edb..ccef8eb 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -22,13 +22,13 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.database.ContentObserver;
-import android.net.Uri;
 import android.os.BatteryManager;
 import android.os.Handler;
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.util.Log;
 import android.util.Slog;
 
 import com.android.systemui.SystemUI;
@@ -39,11 +39,9 @@
 
 public class PowerUI extends SystemUI {
     static final String TAG = "PowerUI";
-    static final boolean DEBUG = false;
-
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private final Handler mHandler = new Handler();
-    private final SettingsObserver mObserver = new SettingsObserver(mHandler);
     private final Receiver mReceiver = new Receiver();
 
     private PowerManager mPowerManager;
@@ -75,17 +73,12 @@
                 false, obs, UserHandle.USER_ALL);
         updateBatteryWarningLevels();
         mReceiver.init();
-        mObserver.init();
     }
 
     private void setSaverMode(boolean mode) {
         mWarnings.showSaverMode(mode);
     }
 
-    private void setSaverTrigger(int level) {
-        mWarnings.setSaverTrigger(level);
-    }
-
     void updateBatteryWarningLevels() {
         int critLevel = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_criticalBatteryWarningLevel);
@@ -143,6 +136,7 @@
             filter.addAction(Intent.ACTION_BATTERY_CHANGED);
             filter.addAction(Intent.ACTION_SCREEN_OFF);
             filter.addAction(Intent.ACTION_SCREEN_ON);
+            filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING);
             filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
             mContext.registerReceiver(this, filter, null, mHandler);
             updateSaverMode();
@@ -214,6 +208,8 @@
                 mScreenOffTime = -1;
             } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)) {
                 updateSaverMode();
+            } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGING.equals(action)) {
+                setSaverMode(intent.getBooleanExtra(PowerManager.EXTRA_POWER_SAVE_MODE, false));
             } else {
                 Slog.w(TAG, "unknown intent: " + intent);
             }
@@ -251,7 +247,6 @@
 
     public interface WarningsUI {
         void update(int batteryLevel, int bucket, long screenOffTime);
-        void setSaverTrigger(int level);
         void showSaverMode(boolean mode);
         void dismissLowBatteryWarning();
         void showLowBatteryWarning(boolean playSound);
@@ -261,29 +256,5 @@
         boolean isInvalidChargerWarningShowing();
         void dump(PrintWriter pw);
     }
-
-    private final class SettingsObserver extends ContentObserver {
-        private final Uri LOW_POWER_MODE_TRIGGER_LEVEL_URI =
-                Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL);
-
-        public SettingsObserver(Handler handler) {
-            super(handler);
-        }
-
-        public void init() {
-            onChange(true, LOW_POWER_MODE_TRIGGER_LEVEL_URI);
-            final ContentResolver cr = mContext.getContentResolver();
-            cr.registerContentObserver(LOW_POWER_MODE_TRIGGER_LEVEL_URI, false, this);
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            if (LOW_POWER_MODE_TRIGGER_LEVEL_URI.equals(uri)) {
-                final int level = Settings.Global.getInt(mContext.getContentResolver(),
-                        Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
-                setSaverTrigger(level);
-            }
-        }
-    }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/CircularClipper.java b/packages/SystemUI/src/com/android/systemui/qs/CircularClipper.java
deleted file mode 100644
index 90275c1..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/CircularClipper.java
+++ /dev/null
@@ -1,74 +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.systemui.qs;
-
-import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
-import android.animation.AnimatorListenerAdapter;
-import android.view.View;
-import android.view.ViewAnimationUtils;
-
-/** Helper for view-level circular clip animations. **/
-public class CircularClipper {
-
-    private final View mTarget;
-
-    private Animator mAnimator;
-
-    public CircularClipper(View target) {
-        mTarget = target;
-    }
-
-    public void animateCircularClip(int x, int y, boolean in, AnimatorListener listener) {
-        if (mAnimator != null) {
-            mAnimator.cancel();
-        }
-        final int w = mTarget.getWidth() - x;
-        final int h = mTarget.getHeight() - y;
-        int r = (int) Math.ceil(Math.sqrt(x * x + y * y));
-        r = (int) Math.max(r, Math.ceil(Math.sqrt(w * w + y * y)));
-        r = (int) Math.max(r, Math.ceil(Math.sqrt(w * w + h * h)));
-        r = (int) Math.max(r, Math.ceil(Math.sqrt(x * x + h * h)));
-
-        mAnimator = ViewAnimationUtils.createCircularReveal(mTarget, x, y, 0, r);
-        mAnimator.removeAllListeners();
-        if (listener != null) {
-            mAnimator.addListener(listener);
-        }
-        if (in) {
-            mAnimator.addListener(mVisibleOnStart);
-            mAnimator.start();
-        } else {
-            mAnimator.addListener(mGoneOnEnd);
-            mAnimator.reverse();
-        }
-    }
-
-    private final AnimatorListenerAdapter mVisibleOnStart = new AnimatorListenerAdapter() {
-        @Override
-        public void onAnimationStart(Animator animation) {
-            mTarget.setVisibility(View.VISIBLE);
-        }
-    };
-
-    private final AnimatorListenerAdapter mGoneOnEnd = new AnimatorListenerAdapter() {
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            mTarget.setVisibility(View.GONE);
-        };
-    };
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java
new file mode 100644
index 0000000..9c1ff9d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs;
+
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
+import android.graphics.drawable.TransitionDrawable;
+import android.view.View;
+import android.view.ViewAnimationUtils;
+
+/** Helper for quick settings detail panel clip animations. **/
+public class QSDetailClipper {
+
+    private final View mDetail;
+    private final TransitionDrawable mBackground;
+
+    private Animator mAnimator;
+
+    public QSDetailClipper(View detail) {
+        mDetail = detail;
+        mBackground = (TransitionDrawable) detail.getBackground();
+    }
+
+    public void animateCircularClip(int x, int y, boolean in, AnimatorListener listener) {
+        if (mAnimator != null) {
+            mAnimator.cancel();
+        }
+        final int w = mDetail.getWidth() - x;
+        final int h = mDetail.getHeight() - y;
+        int r = (int) Math.ceil(Math.sqrt(x * x + y * y));
+        r = (int) Math.max(r, Math.ceil(Math.sqrt(w * w + y * y)));
+        r = (int) Math.max(r, Math.ceil(Math.sqrt(w * w + h * h)));
+        r = (int) Math.max(r, Math.ceil(Math.sqrt(x * x + h * h)));
+        mAnimator = ViewAnimationUtils.createCircularReveal(mDetail, x, y, 0, r);
+        mAnimator.setDuration((long)(mAnimator.getDuration() * 1.5));
+        if (listener != null) {
+            mAnimator.addListener(listener);
+        }
+        mDetail.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+        if (in) {
+            mBackground.startTransition((int)(mAnimator.getDuration() * 0.6));
+            mAnimator.addListener(mVisibleOnStart);
+            mAnimator.start();
+        } else {
+            mDetail.postDelayed(mReverseBackground, (long)(mAnimator.getDuration() * 0.65));
+            mAnimator.addListener(mGoneOnEnd);
+            mAnimator.reverse();
+        }
+    }
+
+    private final Runnable mReverseBackground = new Runnable() {
+        @Override
+        public void run() {
+            if (mAnimator != null) {
+                mBackground.reverseTransition((int)(mAnimator.getDuration() * 0.35));
+            }
+        }
+    };
+
+    private final AnimatorListenerAdapter mVisibleOnStart = new AnimatorListenerAdapter() {
+        @Override
+        public void onAnimationStart(Animator animation) {
+            mDetail.setVisibility(View.VISIBLE);
+        }
+
+        public void onAnimationEnd(Animator animation) {
+            mDetail.setLayerType(View.LAYER_TYPE_NONE, null);
+            mAnimator = null;
+        }
+    };
+
+    private final AnimatorListenerAdapter mGoneOnEnd = new AnimatorListenerAdapter() {
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            mDetail.setLayerType(View.LAYER_TYPE_NONE, null);
+            mDetail.setVisibility(View.GONE);
+            mBackground.resetTransition();
+            mAnimator = null;
+        };
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
new file mode 100644
index 0000000..f04a7b6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.qs;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+import android.view.ContextThemeWrapper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QSTileHost;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
+import com.android.systemui.statusbar.policy.SecurityController;
+import com.android.systemui.statusbar.policy.SecurityController.VpnCallback;
+
+public class QSFooter implements OnClickListener, DialogInterface.OnClickListener {
+    protected static final String TAG = "QSFooter";
+    protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private final View mRootView;
+    private final TextView mFooterText;
+    private final ImageView mFooterIcon;
+    private final Context mContext;
+    private final Callback mCallback = new Callback();
+
+    private SecurityController mSecurityController;
+    private AlertDialog mDialog;
+    private QSTileHost mHost;
+    private Handler mHandler;
+
+    public QSFooter(QSPanel qsPanel, Context context) {
+        mRootView = LayoutInflater.from(context)
+                .inflate(R.layout.quick_settings_footer, qsPanel, false);
+        mRootView.setOnClickListener(this);
+        mFooterText = (TextView) mRootView.findViewById(R.id.footer_text);
+        mFooterIcon = (ImageView) mRootView.findViewById(R.id.footer_icon);
+        mContext = context;
+    }
+
+    public void setHost(QSTileHost host) {
+        mHost = host;
+        mSecurityController = host.getSecurityController();
+        mHandler = new H(host.getLooper());
+    }
+
+    public void setListening(boolean listening) {
+        if (listening) {
+            mSecurityController.addCallback(mCallback);
+        } else {
+            mSecurityController.removeCallback(mCallback);
+        }
+    }
+
+    public View getView() {
+        return mRootView;
+    }
+
+    public boolean hasFooter() {
+        return mRootView.getVisibility() != View.GONE;
+    }
+
+    @Override
+    public void onClick(View v) {
+        mHandler.sendEmptyMessage(H.CLICK);
+    }
+
+    private void handleClick() {
+        mHost.collapsePanels();
+        // TODO: Delay dialog creation until after panels are collapsed.
+        createDialog();
+    }
+
+    public void refreshState() {
+        mHandler.sendEmptyMessage(H.REFRESH_STATE);
+    }
+
+    private void handleRefreshState() {
+        if (mSecurityController.hasDeviceOwner()) {
+            mFooterText.setText(R.string.device_owned_footer);
+            mRootView.setVisibility(View.VISIBLE);
+            mFooterIcon.setVisibility(View.INVISIBLE);
+        } else if (mSecurityController.isVpnEnabled()) {
+            mFooterText.setText(R.string.vpn_footer);
+            mRootView.setVisibility(View.VISIBLE);
+            mFooterIcon.setVisibility(View.VISIBLE);
+        } else {
+            mRootView.setVisibility(View.GONE);
+        }
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        if (which == DialogInterface.BUTTON_NEGATIVE) {
+            if (mSecurityController.isLegacyVpn()) {
+                mSecurityController.disconnectFromLegacyVpn();
+            } else {
+                mSecurityController.openVpnApp();
+            }
+        }
+    }
+
+    private void createDialog() {
+        mDialog = new SystemUIDialog(mContext);
+        mDialog.setTitle(getTitle());
+        mDialog.setMessage(getMessage());
+        mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(), this);
+        if (mSecurityController.isVpnEnabled()) {
+            mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getNegativeButton(), this);
+        }
+        mDialog.show();
+    }
+
+    private String getNegativeButton() {
+        if (mSecurityController.isLegacyVpn()) {
+            return mContext.getString(R.string.disconnect_vpn);
+        } else {
+            return mContext.getString(R.string.open_app);
+        }
+    }
+
+    private String getPositiveButton() {
+        return mContext.getString(R.string.quick_settings_done);
+    }
+
+    private String getMessage() {
+        if (mSecurityController.hasDeviceOwner()) {
+            if (mSecurityController.isVpnEnabled()) {
+                if (mSecurityController.isLegacyVpn()) {
+                    return mContext.getString(
+                            R.string.monitoring_description_legacy_vpn_device_owned,
+                            mSecurityController.getDeviceOwnerName(),
+                            mSecurityController.getLegacyVpnName());
+                } else {
+                    return mContext.getString(R.string.monitoring_description_vpn_device_owned,
+                            mSecurityController.getDeviceOwnerName(),
+                            mSecurityController.getVpnApp());
+                }
+            } else {
+                return mContext.getString(R.string.monitoring_description_device_owned,
+                        mSecurityController.getDeviceOwnerName());
+            }
+        } else {
+            if (mSecurityController.isLegacyVpn()) {
+                return mContext.getString(R.string.monitoring_description_legacy_vpn,
+                        mSecurityController.getLegacyVpnName());
+
+            } else {
+                return mContext.getString(R.string.monitoring_description_vpn,
+                        mSecurityController.getVpnApp());
+            }
+        }
+    }
+
+    private int getTitle() {
+        if (mSecurityController.hasDeviceOwner()) {
+            return R.string.monitoring_title_device_owned;
+        }
+        return R.string.monitoring_title;
+    }
+
+    private class Callback implements VpnCallback {
+        @Override
+        public void onVpnStateChanged() {
+            refreshState();
+        }
+    }
+
+    private class H extends Handler {
+        private static final int CLICK = 0;
+        private static final int REFRESH_STATE = 1;
+
+        private H(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            String name = null;
+            try {
+                if (msg.what == REFRESH_STATE) {
+                    name = "handleRefreshState";
+                    handleRefreshState();
+                } else if (msg.what == CLICK) {
+                    name = "handleClick";
+                    handleClick();
+                }
+            } catch (Throwable t) {
+                final String error = "Error in " + name;
+                Log.w(TAG, error, t);
+                mHost.warn(error, t);
+            }
+        }
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 4901f40..59f3b3d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -49,7 +49,7 @@
     private final View mDetailSettingsButton;
     private final View mDetailDoneButton;
     private final View mBrightnessView;
-    private final CircularClipper mClipper;
+    private final QSDetailClipper mClipper;
     private final H mHandler = new H();
 
     private int mColumns;
@@ -67,6 +67,8 @@
     private BrightnessController mBrightnessController;
     private QSTileHost mHost;
 
+    private QSFooter mFooter;
+
     public QSPanel(Context context) {
         this(context, null);
     }
@@ -83,9 +85,11 @@
         mDetail.setClickable(true);
         mBrightnessView = LayoutInflater.from(context).inflate(
                 R.layout.quick_settings_brightness_dialog, this, false);
+        mFooter = new QSFooter(this, context);
         addView(mDetail);
         addView(mBrightnessView);
-        mClipper = new CircularClipper(mDetail);
+        addView(mFooter.getView());
+        mClipper = new QSDetailClipper(mDetail);
         updateResources();
 
         mBrightnessController = new BrightnessController(getContext(),
@@ -95,7 +99,7 @@
         mDetailDoneButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
-                showDetail(false, mDetailRecord);
+                closeDetail();
             }
         });
     }
@@ -106,6 +110,7 @@
 
     public void setHost(QSTileHost host) {
         mHost = host;
+        mFooter.setHost(host);
     }
 
     public QSTileHost getHost() {
@@ -134,7 +139,7 @@
         if (mExpanded == expanded) return;
         mExpanded = expanded;
         if (!mExpanded) {
-            showDetail(false /*show*/, mDetailRecord);
+            closeDetail();
         }
     }
 
@@ -144,6 +149,7 @@
         for (TileRecord r : mRecords) {
             r.tile.setListening(mListening);
         }
+        mFooter.setListening(mListening);
         if (mListening) {
             refreshAllTiles();
         }
@@ -158,6 +164,7 @@
         for (TileRecord r : mRecords) {
             r.tile.refreshState();
         }
+        mFooter.refreshState();
     }
 
     public void showDetailAdapter(boolean show, DetailAdapter adapter) {
@@ -226,6 +233,14 @@
         addView(r.tileView);
     }
 
+    public boolean isShowingDetail() {
+        return mDetailRecord != null;
+    }
+
+    public void closeDetail() {
+        showDetail(false, mDetailRecord);
+    }
+
     private void handleShowDetail(Record r, boolean show) {
         if (r instanceof TileRecord) {
             handleShowDetailTile((TileRecord) r, show);
@@ -279,6 +294,7 @@
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         final int width = MeasureSpec.getSize(widthMeasureSpec);
         mBrightnessView.measure(exactly(width), MeasureSpec.UNSPECIFIED);
+        mFooter.getView().measure(exactly(width), MeasureSpec.UNSPECIFIED);
         int r = -1;
         int c = -1;
         int rows = 0;
@@ -307,6 +323,9 @@
             record.tileView.measure(exactly(cw), exactly(ch));
         }
         int h = rows == 0 ? mBrightnessView.getHeight() : (getRowTop(rows) + mPanelPaddingBottom);
+        if (mFooter.hasFooter()) {
+            h += mFooter.getView().getHeight();
+        }
         mDetail.measure(exactly(width), exactly(h));
         setMeasuredDimension(width, h);
     }
@@ -333,6 +352,11 @@
         }
         final int dh = Math.max(mDetail.getMeasuredHeight(), getMeasuredHeight());
         mDetail.layout(0, 0, mDetail.getMeasuredWidth(), dh);
+        if (mFooter.hasFooter()) {
+            View footer = mFooter.getView();
+            footer.layout(0, getMeasuredHeight() - footer.getMeasuredHeight(),
+                    footer.getMeasuredWidth(), getMeasuredHeight());
+        }
     }
 
     private int getRowTop(int row) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
index 6697751..1a555f1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
@@ -57,7 +57,7 @@
         mSignal = new ImageView(mContext);
         mIconFrame.addView(mSignal);
         mOverlay = new ImageView(mContext);
-        mIconFrame.addView(mOverlay);
+        mIconFrame.addView(mOverlay, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
         return mIconFrame;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/UsageTracker.java b/packages/SystemUI/src/com/android/systemui/qs/UsageTracker.java
new file mode 100644
index 0000000..e72d3a9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/UsageTracker.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+
+import com.android.systemui.R;
+
+public class UsageTracker {
+    private static final long MILLIS_PER_DAY = 1000 * 60 * 60 * 24;
+
+    private final Context mContext;
+    private final long mTimeToShowTile;
+    private final String mPrefKey;
+    private final String mResetAction;
+
+    private BroadcastReceiver mReceiver;
+
+    public UsageTracker(Context context, Class<?> tile) {
+        mContext = context;
+        mPrefKey = tile.getSimpleName() + "LastUsed";
+        mTimeToShowTile = MILLIS_PER_DAY * mContext.getResources()
+                .getInteger(R.integer.days_to_show_timeout_tiles);
+        mResetAction = "com.android.systemui.qs." + tile.getSimpleName() + ".usage_reset";
+    }
+
+    public void listenForReset() {
+        if (mReceiver != null) {
+            mReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    if (mResetAction.equals(intent.getAction())) {
+                        reset();
+                    }
+                }
+            };
+            mContext.registerReceiver(mReceiver, new IntentFilter(mResetAction));
+        }
+    }
+
+    public boolean isRecentlyUsed() {
+        long lastUsed = getSharedPrefs().getLong(mPrefKey, 0);
+        return (System.currentTimeMillis() - lastUsed) < mTimeToShowTile;
+    }
+
+    public void trackUsage() {
+        getSharedPrefs().edit().putLong(mPrefKey, System.currentTimeMillis()).commit();
+    }
+
+    public void reset() {
+        getSharedPrefs().edit().remove(mPrefKey).commit();
+    }
+
+    private SharedPreferences getSharedPrefs() {
+        return mContext.getSharedPreferences(mContext.getPackageName(), 0);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 42da282..ce42d47 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -91,10 +91,9 @@
         if (cb == null) return;
 
         final Resources r = mContext.getResources();
-        state.iconId = cb.noSim
-                ? R.drawable.stat_sys_no_sim
-                : cb.enabled && (cb.mobileSignalIconId > 0) && !cb.airplaneModeEnabled
-                ? cb.mobileSignalIconId
+        state.iconId = cb.noSim ? R.drawable.stat_sys_no_sim
+                : !cb.enabled || cb.airplaneModeEnabled ? R.drawable.ic_qs_signal_disabled
+                : cb.mobileSignalIconId > 0 ? cb.mobileSignalIconId
                 : R.drawable.ic_qs_signal_no_signal;
         state.overlayIconId = cb.enabled && (cb.dataTypeIconId > 0) && !cb.wifiConnected
                 ? cb.dataTypeIconId
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index 7c2c7c3..9c88466 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -21,13 +21,13 @@
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.qs.SecureSetting;
+import com.android.systemui.qs.UsageTracker;
 
 /** Quick settings tile: Invert colors **/
 public class ColorInversionTile extends QSTile<QSTile.BooleanState> {
 
     private final SecureSetting mSetting;
-
-    private boolean mVisible;
+    private final UsageTracker mUsageTracker;
 
     public ColorInversionTile(Host host) {
         super(host);
@@ -37,8 +37,11 @@
             @Override
             protected void handleValueChanged(int value) {
                 handleRefreshState(value);
+                mUsageTracker.trackUsage();
             }
         };
+        mUsageTracker = new UsageTracker(host.getContext(), ColorInversionTile.class);
+        mUsageTracker.listenForReset();
     }
 
     @Override
@@ -65,10 +68,7 @@
     protected void handleUpdateState(BooleanState state, Object arg) {
         final int value = arg instanceof Integer ? (Integer) arg : mSetting.getValue();
         final boolean enabled = value != 0;
-        if (enabled) {
-            mVisible = true;
-        }
-        state.visible = mVisible;
+        state.visible = enabled || mUsageTracker.isRecentlyUsed();
         state.value = enabled;
         state.label = mContext.getString(R.string.quick_settings_inversion_label);
         state.iconId = enabled ? R.drawable.ic_qs_inversion_on : R.drawable.ic_qs_inversion_off;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index c46632d..f4ddd84 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -24,13 +24,20 @@
 import android.app.ActivityManager;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.SystemClock;
 import android.provider.Settings.Secure;
+import android.util.Log;
 
 /** Quick settings tile: Control flashlight **/
 public class FlashlightTile extends QSTile<QSTile.BooleanState> implements
         FlashlightController.FlashlightListener {
 
+    /** Grace period for which we consider the flashlight
+     * still available because it was recently on. */
+    private static final long RECENTLY_ON_DURATION_MILLIS = 500;
+
     private final FlashlightController mFlashlightController;
+    private long mWasLastOn;
 
     public FlashlightTile(Host host) {
         super(host);
@@ -63,12 +70,26 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
+        if (state.value) {
+            mWasLastOn = SystemClock.uptimeMillis();
+        }
+
         if (arg instanceof Boolean) {
             state.value = (Boolean) arg;
         }
-        // Always show the tile when the flashlight is on. This is needed because
+
+        if (!state.value && mWasLastOn != 0) {
+            if (SystemClock.uptimeMillis() > mWasLastOn + RECENTLY_ON_DURATION_MILLIS) {
+                mWasLastOn = 0;
+            } else {
+                mHandler.removeCallbacks(mRecentlyOnTimeout);
+                mHandler.postAtTime(mRecentlyOnTimeout, mWasLastOn + RECENTLY_ON_DURATION_MILLIS);
+            }
+        }
+
+        // Always show the tile when the flashlight is or was recently on. This is needed because
         // the camera is not available while it is being used for the flashlight.
-        state.visible = state.value || mFlashlightController.isAvailable();
+        state.visible = mWasLastOn != 0 || mFlashlightController.isAvailable();
         state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
         state.iconId = state.value
                 ? R.drawable.ic_qs_flashlight_on : R.drawable.ic_qs_flashlight_off;
@@ -88,4 +109,11 @@
     public void onFlashlightAvailabilityChanged(boolean available) {
         refreshState();
     }
+
+    private Runnable mRecentlyOnTimeout = new Runnable() {
+        @Override
+        public void run() {
+            refreshState();
+        }
+    };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index e0b465e..ff26b54 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -19,27 +19,23 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.SharedPreferences;
 
 import com.android.systemui.R;
+import com.android.systemui.qs.UsageTracker;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.policy.HotspotController;
 
 /** Quick settings tile: Hotspot **/
 public class HotspotTile extends QSTile<QSTile.BooleanState> {
-    private static final String KEY_LAST_USED_DATE = "lastUsedDate";
-    private static final long MILLIS_PER_DAY = 1000 * 60 * 60 * 24;
-
     private final HotspotController mController;
     private final Callback mCallback = new Callback();
-    private final long mTimeToShowTile;
+    private final UsageTracker mUsageTracker;
 
     public HotspotTile(Host host) {
         super(host);
         mController = host.getHotspotController();
-
-        mTimeToShowTile = MILLIS_PER_DAY
-                * mContext.getResources().getInteger(R.integer.days_to_show_hotspot);
+        mUsageTracker = new UsageTracker(host.getContext(), HotspotTile.class);
+        mUsageTracker.listenForReset();
     }
 
     @Override
@@ -64,7 +60,7 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
-        state.visible = mController.isHotspotSupported() && isHotspotRecentlyUsed();
+        state.visible = mController.isHotspotSupported() && mUsageTracker.isRecentlyUsed();
         state.label = mContext.getString(R.string.quick_settings_hotspot_label);
 
         state.value = mController.isHotspotEnabled();
@@ -72,15 +68,6 @@
                 : R.drawable.ic_qs_hotspot_off;
     }
 
-    private boolean isHotspotRecentlyUsed() {
-        long lastDay = getSharedPrefs(mContext).getLong(KEY_LAST_USED_DATE, 0);
-        return (System.currentTimeMillis() - lastDay) < mTimeToShowTile;
-    }
-
-    private static SharedPreferences getSharedPrefs(Context context) {
-        return context.getSharedPreferences(context.getPackageName(), 0);
-    }
-
     private final class Callback implements HotspotController.Callback {
         @Override
         public void onHotspotChanged(boolean enabled) {
@@ -93,10 +80,14 @@
      * the hotspot tile for a number of days after use.
      */
     public static class APChangedReceiver extends BroadcastReceiver {
+        private UsageTracker mUsageTracker;
+
         @Override
         public void onReceive(Context context, Intent intent) {
-            long currentTime = System.currentTimeMillis();
-            getSharedPrefs(context).edit().putLong(KEY_LAST_USED_DATE, currentTime).commit();
+            if (mUsageTracker == null) {
+                mUsageTracker = new UsageTracker(context, HotspotTile.class);
+            }
+            mUsageTracker.trackUsage();
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 1707b32..5651d49 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -113,7 +113,11 @@
         state.filter = true;
         final String signalContentDescription;
         final Resources r = mContext.getResources();
-        if (wifiConnected) {
+        if (!state.enabled) {
+            state.iconId = R.drawable.ic_qs_wifi_disabled;
+            state.label = r.getString(R.string.quick_settings_wifi_label);
+            signalContentDescription = r.getString(R.string.accessibility_wifi_off);
+        } else if (wifiConnected) {
             state.iconId = cb.wifiSignalIconId;
             state.label = removeDoubleQuotes(cb.enabledDesc);
             signalContentDescription = cb.wifiSignalContentDescription;
diff --git a/packages/SystemUI/src/com/android/systemui/recent/Recents.java b/packages/SystemUI/src/com/android/systemui/recent/Recents.java
index e03c01c..4cf5fe1 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/Recents.java
@@ -77,9 +77,9 @@
     }
 
     @Override
-    public void hideRecents(boolean triggeredFromAltTab) {
+    public void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
         if (mUseAlternateRecents) {
-            mAlternateRecents.onHideRecents(triggeredFromAltTab);
+            mAlternateRecents.onHideRecents(triggeredFromAltTab, triggeredFromHomeKey);
         } else {
             Intent intent = new Intent(RecentsActivity.CLOSE_RECENTS_INTENT);
             intent.setPackage("com.android.systemui");
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index 0b08b93..a55c0f2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -51,8 +51,13 @@
     final public static String EXTRA_FROM_HOME = "recents.triggeredOverHome";
     final public static String EXTRA_FROM_APP_THUMBNAIL = "recents.animatingWithThumbnail";
     final public static String EXTRA_FROM_APP_FULL_SCREENSHOT = "recents.thumbnail";
+    final public static String EXTRA_FROM_TASK_ID = "recents.activeTaskId";
     final public static String EXTRA_TRIGGERED_FROM_ALT_TAB = "recents.triggeredFromAltTab";
-    final public static String EXTRA_TRIGGERED_FROM_TASK_ID = "recents.activeTaskId";
+    final public static String EXTRA_TRIGGERED_FROM_HOME_KEY = "recents.triggeredFromHomeKey";
+
+    final public static String ACTION_START_ENTER_ANIMATION = "action_start_enter_animation";
+    final public static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity";
+    final public static String ACTION_HIDE_RECENTS_ACTIVITY = "action_hide_recents_activity";
 
     final static int sMinToggleDelay = 425;
 
@@ -126,14 +131,15 @@
     }
 
     /** Hides the recents */
-    public void onHideRecents(boolean triggeredFromAltTab) {
+    public void onHideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
         if (mBootCompleted) {
             if (isRecentsTopMost(getTopMostTask(), null)) {
                 // Notify recents to hide itself
-                Intent intent = new Intent(RecentsActivity.ACTION_HIDE_RECENTS_ACTIVITY);
+                Intent intent = new Intent(ACTION_HIDE_RECENTS_ACTIVITY);
                 intent.setPackage(mContext.getPackageName());
                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-                intent.putExtra(RecentsActivity.EXTRA_TRIGGERED_FROM_ALT_TAB, triggeredFromAltTab);
+                intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, triggeredFromAltTab);
+                intent.putExtra(EXTRA_TRIGGERED_FROM_HOME_KEY, triggeredFromHomeKey);
                 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
             }
         }
@@ -220,7 +226,7 @@
         AtomicBoolean isTopTaskHome = new AtomicBoolean();
         if (isRecentsTopMost(topTask, isTopTaskHome)) {
             // Notify recents to toggle itself
-            Intent intent = new Intent(RecentsActivity.ACTION_TOGGLE_RECENTS_ACTIVITY);
+            Intent intent = new Intent(ACTION_TOGGLE_RECENTS_ACTIVITY);
             intent.setPackage(mContext.getPackageName());
             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
             mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
@@ -403,7 +409,7 @@
             intent.putExtra(extraFlag, true);
         }
         intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, mTriggeredFromAltTab);
-        intent.putExtra(EXTRA_TRIGGERED_FROM_TASK_ID, (topTask != null) ? topTask.id : -1);
+        intent.putExtra(EXTRA_FROM_TASK_ID, (topTask != null) ? topTask.id : -1);
         if (opts != null) {
             mContext.startActivityAsUser(intent, opts.toBundle(), UserHandle.CURRENT);
         } else {
@@ -442,7 +448,7 @@
     public void onAnimationStarted() {
         // Notify recents to start the enter animation
         if (!mStartAnimationTriggered) {
-            Intent intent = new Intent(RecentsActivity.ACTION_START_ENTER_ANIMATION);
+            Intent intent = new Intent(ACTION_START_ENTER_ANIMATION);
             intent.setPackage(mContext.getPackageName());
             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
             mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 4534897..417049c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -59,12 +59,6 @@
         RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks,
         DebugOverlayView.DebugOverlayViewCallbacks {
 
-    // Actions and Extras sent from AlternateRecentsComponent
-    final static String EXTRA_TRIGGERED_FROM_ALT_TAB = "extra_triggered_from_alt_tab";
-    final static String ACTION_START_ENTER_ANIMATION = "action_start_enter_animation";
-    final static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity";
-    final static String ACTION_HIDE_RECENTS_ACTIVITY = "action_hide_recents_activity";
-
     RecentsConfiguration mConfig;
     boolean mVisible;
 
@@ -131,18 +125,22 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
-            if (action.equals(ACTION_HIDE_RECENTS_ACTIVITY)) {
-                if (intent.getBooleanExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, false)) {
+            if (action.equals(AlternateRecentsComponent.ACTION_HIDE_RECENTS_ACTIVITY)) {
+                // Mark Recents as no longer visible
+                AlternateRecentsComponent.notifyVisibilityChanged(false);
+                if (intent.getBooleanExtra(AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false)) {
                     // If we are hiding from releasing Alt-Tab, dismiss Recents to the focused app
                     dismissRecentsToFocusedTaskOrHome(false);
-                } else {
+                } else if (intent.getBooleanExtra(AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_HOME_KEY, false)) {
                     // Otherwise, dismiss Recents to Home
                     dismissRecentsToHome(true);
+                } else {
+                    // Do nothing, another activity is being launched on top of Recents
                 }
-            } else if (action.equals(ACTION_TOGGLE_RECENTS_ACTIVITY)) {
+            } else if (action.equals(AlternateRecentsComponent.ACTION_TOGGLE_RECENTS_ACTIVITY)) {
                 // If we are toggling Recents, then first unfilter any filtered stacks first
                 dismissRecentsToFocusedTaskOrHome(true);
-            } else if (action.equals(ACTION_START_ENTER_ANIMATION)) {
+            } else if (action.equals(AlternateRecentsComponent.ACTION_START_ENTER_ANIMATION)) {
                 // Try and start the enter animation (or restart it on configuration changed)
                 ReferenceCountedTrigger t = new ReferenceCountedTrigger(context, null, null, null);
                 mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(t));
@@ -195,11 +193,11 @@
                 AlternateRecentsComponent.EXTRA_FROM_APP_THUMBNAIL, false);
         mConfig.launchedFromAppWithScreenshot = launchIntent.getBooleanExtra(
                 AlternateRecentsComponent.EXTRA_FROM_APP_FULL_SCREENSHOT, false);
+        mConfig.launchedToTaskId = launchIntent.getIntExtra(
+                AlternateRecentsComponent.EXTRA_FROM_TASK_ID, -1);
         mConfig.launchedWithAltTab = launchIntent.getBooleanExtra(
                 AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false);
         mConfig.launchedWithNoRecentTasks = !root.hasTasks();
-        mConfig.launchedToTaskId = launchIntent.getIntExtra(
-                AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_TASK_ID, -1);
 
         // Mark the task that is the launch target
         int taskStackCount = stacks.size();
@@ -383,9 +381,6 @@
         filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);
         registerReceiver(mSystemBroadcastReceiver, filter);
 
-        // Register any broadcast receivers for the task loader
-        RecentsTaskLoader.getInstance().registerReceivers(this, mRecentsView);
-
         // Private API calls to make the shadows look better
         try {
             Utilities.setShadowProperty("ambientShadowStrength", String.valueOf(35f));
@@ -447,10 +442,13 @@
 
         // Register the broadcast receiver to handle messages from our service
         IntentFilter filter = new IntentFilter();
-        filter.addAction(ACTION_HIDE_RECENTS_ACTIVITY);
-        filter.addAction(ACTION_TOGGLE_RECENTS_ACTIVITY);
-        filter.addAction(ACTION_START_ENTER_ANIMATION);
+        filter.addAction(AlternateRecentsComponent.ACTION_HIDE_RECENTS_ACTIVITY);
+        filter.addAction(AlternateRecentsComponent.ACTION_TOGGLE_RECENTS_ACTIVITY);
+        filter.addAction(AlternateRecentsComponent.ACTION_START_ENTER_ANIMATION);
         registerReceiver(mServiceBroadcastReceiver, filter);
+
+        // Register any broadcast receivers for the task loader
+        RecentsTaskLoader.getInstance().registerReceivers(this, mRecentsView);
     }
 
     @Override
@@ -481,9 +479,15 @@
     protected void onStop() {
         super.onStop();
 
+        // Remove all the views
+        mRecentsView.removeAllTaskStacks();
+
         // Unregister the RecentsService receiver
         unregisterReceiver(mServiceBroadcastReceiver);
 
+        // Unregister any broadcast receivers for the task loader
+        RecentsTaskLoader.getInstance().unregisterReceivers();
+
         // Stop listening for widget package changes if there was one bound
         if (mAppWidgetHost.isListening()) {
             mAppWidgetHost.stopListening();
@@ -496,7 +500,6 @@
 
         // Unregister the system broadcast receivers
         unregisterReceiver(mSystemBroadcastReceiver);
-        RecentsTaskLoader.getInstance().unregisterReceivers();
     }
 
     @Override
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 cd2cbe7..1a32b81 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -121,6 +121,17 @@
         }
     }
 
+    /** Removes all the task stack views from this recents view. */
+    public void removeAllTaskStacks() {
+        int childCount = getChildCount();
+        for (int i = childCount - 1; i >= 0; i--) {
+            View child = getChildAt(i);
+            if (child != mSearchBar) {
+                removeViewAt(i);
+            }
+        }
+    }
+
     /** Launches the focused task from the first stack if possible */
     public boolean launchFocusedTask() {
         // Get the first stack view
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 986df91..57f1274 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -428,11 +428,11 @@
 
     @Override
     public void computeScroll() {
+        mStackScroller.computeScroll();
         // Synchronize the views
         if (synchronizeStackViewsWithModel()) {
             clipTaskViews();
         }
-        mStackScroller.computeScroll();
     }
 
     /** Computes the stack and task rects */
@@ -632,12 +632,6 @@
         }
     }
 
-    @Override
-    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
-        super.onScrollChanged(l, t, oldl, oldt);
-        requestSynchronizeStackViewsWithModel();
-    }
-
     public boolean isTransformedTouchPointInView(float x, float y, View child) {
         return isTransformedTouchPointInView(x, y, child, null);
     }
@@ -889,7 +883,7 @@
     public void onScrollChanged(float p) {
         mUIDozeTrigger.poke();
         requestSynchronizeStackViewsWithModel();
-        invalidate();
+        postInvalidateOnAnimation();
     }
 
     /**** RecentsPackageMonitor.PackageCallbacks Implementation ****/
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 4cf6b82..374a27f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -185,6 +185,7 @@
 
     /** Handles touch events once we have intercepted them */
     public boolean onTouchEvent(MotionEvent ev) {
+
         // Short circuit if we have no children
         boolean hasChildren = (mSv.getChildCount() > 0);
         if (!hasChildren) {
@@ -278,7 +279,6 @@
                 final VelocityTracker velocityTracker = mVelocityTracker;
                 velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
                 int velocity = (int) velocityTracker.getYVelocity(mActivePointerId);
-
                 if (mIsScrolling && (Math.abs(velocity) > mMinimumVelocity)) {
                     // XXX: Should this be calculated as a percentage of a curve?
                     int overscrollRange = (int) (Math.min(1f,
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 5771299..c559253 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -74,6 +74,8 @@
     Runnable finisher;
     int iconSize;
     int result;
+    int previewWidth;
+    int previewheight;
 
     void clearImage() {
         image = null;
@@ -131,17 +133,19 @@
         mImageWidth = data.image.getWidth();
         mImageHeight = data.image.getHeight();
         int iconSize = data.iconSize;
+        int previewWidth = data.previewWidth;
+        int previewHeight = data.previewheight;
 
         final int shortSide = mImageWidth < mImageHeight ? mImageWidth : mImageHeight;
-        Bitmap preview = Bitmap.createBitmap(shortSide, shortSide, data.image.getConfig());
+        Bitmap preview = Bitmap.createBitmap(previewWidth, previewHeight, data.image.getConfig());
         Canvas c = new Canvas(preview);
         Paint paint = new Paint();
         ColorMatrix desat = new ColorMatrix();
         desat.setSaturation(0.25f);
         paint.setColorFilter(new ColorMatrixColorFilter(desat));
         Matrix matrix = new Matrix();
-        matrix.postTranslate((shortSide - mImageWidth) / 2,
-                            (shortSide - mImageHeight) / 2);
+        matrix.postTranslate((previewWidth - mImageWidth) / 2,
+                            (previewHeight - mImageHeight) / 2);
         c.drawBitmap(data.image, matrix, paint);
         c.drawColor(0x40FFFFFF);
         c.setBitmap(null);
@@ -343,6 +347,8 @@
     private static final float SCREENSHOT_DROP_OUT_MIN_SCALE = SCREENSHOT_SCALE * 0.45f;
     private static final float SCREENSHOT_FAST_DROP_OUT_MIN_SCALE = SCREENSHOT_SCALE * 0.6f;
     private static final float SCREENSHOT_DROP_OUT_MIN_SCALE_OFFSET = 0f;
+    private final int mPreviewWidth;
+    private final int mPreviewHeight;
 
     private Context mContext;
     private WindowManager mWindowManager;
@@ -418,6 +424,16 @@
         mBgPadding = (float) r.getDimensionPixelSize(R.dimen.global_screenshot_bg_padding);
         mBgPaddingScale = mBgPadding /  mDisplayMetrics.widthPixels;
 
+        // determine the optimal preview size
+        int panelWidth = 0;
+        try {
+            panelWidth = r.getDimensionPixelSize(R.dimen.notification_panel_width);
+        } catch (Resources.NotFoundException e) {
+            panelWidth = mDisplayMetrics.widthPixels;
+        }
+        mPreviewWidth = panelWidth;
+        mPreviewHeight = r.getDimensionPixelSize(R.dimen.notification_max_height);
+
         // Setup the Camera shutter sound
         mCameraSound = new MediaActionSound();
         mCameraSound.load(MediaActionSound.SHUTTER_CLICK);
@@ -432,6 +448,8 @@
         data.image = mScreenBitmap;
         data.iconSize = mNotificationIconSize;
         data.finisher = finisher;
+        data.previewWidth = mPreviewWidth;
+        data.previewheight = mPreviewHeight;
         if (mSaveInBgTask != null) {
             mSaveInBgTask.cancel(false);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 4d7698a..1cd18a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -43,7 +43,6 @@
 import android.view.animation.PathInterpolator;
 
 import com.android.systemui.R;
-import com.android.systemui.statusbar.stack.StackStateAnimator;
 
 /**
  * Base class for both {@link ExpandableNotificationRow} and {@link NotificationOverflowContainer}
@@ -449,19 +448,20 @@
     }
 
     @Override
-    public void performRemoveAnimation(float translationDirection, Runnable onFinishedRunnable) {
+    public void performRemoveAnimation(long duration, float translationDirection,
+            Runnable onFinishedRunnable) {
         enableAppearDrawing(true);
         if (mDrawingAppearAnimation) {
             startAppearAnimation(false /* isAppearing */, translationDirection,
-                    0, onFinishedRunnable);
+                    0, duration, onFinishedRunnable);
         }
     }
 
     @Override
-    public void performAddAnimation(long delay) {
+    public void performAddAnimation(long delay, long duration) {
         enableAppearDrawing(true);
         if (mDrawingAppearAnimation) {
-            startAppearAnimation(true /* isAppearing */, -1.0f, delay, null);
+            startAppearAnimation(true /* isAppearing */, -1.0f, delay, duration, null);
         }
     }
 
@@ -470,8 +470,8 @@
         mScrimView.setAlpha(scrimAmount);
     }
 
-    private void startAppearAnimation(boolean isAppearing,
-            float translationDirection, long delay, final Runnable onFinishedRunnable) {
+    private void startAppearAnimation(boolean isAppearing, float translationDirection, long delay,
+            long duration, final Runnable onFinishedRunnable) {
         if (mAppearAnimator != null) {
             mAppearAnimator.cancel();
         }
@@ -501,8 +501,7 @@
                 targetValue);
         mAppearAnimator.setInterpolator(mLinearInterpolator);
         mAppearAnimator.setDuration(
-                (long) (StackStateAnimator.ANIMATION_DURATION_APPEAR_DISAPPEAR
-                        * Math.abs(mAppearAnimationFraction - targetValue)));
+                (long) (duration * Math.abs(mAppearAnimationFraction - targetValue)));
         mAppearAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
             @Override
             public void onAnimationUpdate(ValueAnimator animation) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 4b037d2..16e51c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -98,7 +98,7 @@
         RecentsComponent.Callbacks, ExpandableNotificationRow.ExpansionLogger,
         NotificationData.Environment {
     public static final String TAG = "StatusBar";
-    public static final boolean DEBUG = false;
+    public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     public static final boolean MULTIUSER_DEBUG = false;
 
     protected static final int MSG_SHOW_RECENT_APPS = 1019;
@@ -152,6 +152,7 @@
     private Locale mLocale;
     protected boolean mUseHeadsUp = false;
     protected boolean mHeadsUpTicker = false;
+    protected boolean mDisableNotificationAlerts = false;
 
     protected IDreamManager mDreamManager;
     PowerManager mPowerManager;
@@ -200,6 +201,7 @@
 
     protected NotificationOverflowContainer mKeyguardIconOverflowContainer;
     protected DismissView mDismissView;
+    protected EmptyShadeView mEmptyShadeView;
 
     @Override  // NotificationData.Environment
     public boolean isDeviceProvisioned() {
@@ -218,9 +220,8 @@
             final int mode = Settings.Global.getInt(mContext.getContentResolver(),
                     Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
             setZenMode(mode);
-            final boolean show = Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1) != 0;
-            mShowLockscreenNotifications = show;
+
+            updateLockscreenNotificationSetting();
         }
     };
 
@@ -287,6 +288,9 @@
                 mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
                 updateCurrentProfilesCache();
                 if (true) Log.v(TAG, "userId " + mCurrentUserId + " is in the house");
+
+                updateLockscreenNotificationSetting();
+
                 userSwitched(mCurrentUserId);
             } else if (Intent.ACTION_USER_ADDED.equals(action)) {
                 updateCurrentProfilesCache();
@@ -385,8 +389,9 @@
                 Settings.Global.getUriFor(Settings.Global.ZEN_MODE), false,
                 mSettingsObserver);
         mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS), false,
-                mSettingsObserver);
+                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS), false,
+                mSettingsObserver,
+                UserHandle.USER_ALL);
 
         mContext.getContentResolver().registerContentObserver(
                 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
@@ -682,10 +687,11 @@
     }
 
     @Override
-    public void hideRecentApps(boolean triggeredFromAltTab) {
+    public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
         int msg = MSG_HIDE_RECENT_APPS;
         mHandler.removeMessages(msg);
-        mHandler.obtainMessage(msg, triggeredFromAltTab ? 1 : 0, 0).sendToTarget();
+        mHandler.obtainMessage(msg, triggeredFromAltTab ? 1 : 0,
+                triggeredFromHomeKey ? 1 : 0).sendToTarget();
     }
 
     @Override
@@ -795,9 +801,9 @@
         }
     }
 
-    protected void hideRecents(boolean triggeredFromAltTab) {
+    protected void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
         if (mRecents != null) {
-            mRecents.hideRecents(triggeredFromAltTab);
+            mRecents.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
         }
     }
 
@@ -888,13 +894,12 @@
 
     protected class H extends Handler {
         public void handleMessage(Message m) {
-            Intent intent;
             switch (m.what) {
              case MSG_SHOW_RECENT_APPS:
                  showRecents(m.arg1 > 0);
                  break;
              case MSG_HIDE_RECENT_APPS:
-                 hideRecents(m.arg1 > 0);
+                 hideRecents(m.arg1 > 0, m.arg2 > 0);
                  break;
              case MSG_TOGGLE_RECENTS_APPS:
                  toggleRecents();
@@ -909,14 +914,12 @@
                  if (DEBUG) Log.d(TAG, "opening search panel");
                  if (mSearchPanelView != null && mSearchPanelView.isAssistantAvailable()) {
                      mSearchPanelView.show(true, true);
-                     onShowSearchPanel();
                  }
                  break;
              case MSG_CLOSE_SEARCH_PANEL:
                  if (DEBUG) Log.d(TAG, "closing search panel");
                  if (mSearchPanelView != null && mSearchPanelView.isShowing()) {
                      mSearchPanelView.show(false, true);
-                     onHideSearchPanel();
                  }
                  break;
             }
@@ -948,12 +951,6 @@
     protected void workAroundBadLayerDrawableOpacity(View v) {
     }
 
-    protected void onHideSearchPanel() {
-    }
-
-    protected void onShowSearchPanel() {
-    }
-
     private boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
             return inflateViews(entry, parent, false);
     }
@@ -1148,7 +1145,7 @@
 
             if (profileIcon != null) {
                 Drawable profileDrawable
-                        = mUserManager.getBadgeForUser(entry.notification.getUser());
+                        = mUserManager.getBadgeForUser(entry.notification.getUser(), 0);
                 if (profileDrawable != null) {
                     profileIcon.setImageDrawable(profileDrawable);
                     profileIcon.setVisibility(View.VISIBLE);
@@ -1324,31 +1321,30 @@
         return entry.notification;
     }
 
-    protected NotificationData.Entry createNotificationViews(StatusBarNotification notification) {
+    protected NotificationData.Entry createNotificationViews(StatusBarNotification sbn) {
         if (DEBUG) {
-            Log.d(TAG, "createNotificationViews(notification=" + notification);
+            Log.d(TAG, "createNotificationViews(notification=" + sbn);
         }
         // Construct the icon.
+        Notification n = sbn.getNotification();
         final StatusBarIconView iconView = new StatusBarIconView(mContext,
-                notification.getPackageName() + "/0x" + Integer.toHexString(notification.getId()),
-                notification.getNotification());
+                sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), n);
         iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
 
-        final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
-                notification.getUser(),
-                    notification.getNotification().icon,
-                    notification.getNotification().iconLevel,
-                    notification.getNotification().number,
-                    notification.getNotification().tickerText);
+        final StatusBarIcon ic = new StatusBarIcon(sbn.getPackageName(),
+                sbn.getUser(),
+                    n.icon,
+                    n.iconLevel,
+                    n.number,
+                    n.tickerText);
         if (!iconView.set(ic)) {
-            handleNotificationError(notification, "Couldn't create icon: " + ic);
+            handleNotificationError(sbn, "Couldn't create icon: " + ic);
             return null;
         }
         // Construct the expanded view.
-        NotificationData.Entry entry = new NotificationData.Entry(notification, iconView);
+        NotificationData.Entry entry = new NotificationData.Entry(sbn, iconView);
         if (!inflateViews(entry, mStackScroller)) {
-            handleNotificationError(notification, "Couldn't expand RemoteViews for: "
-                    + notification);
+            handleNotificationError(sbn, "Couldn't expand RemoteViews for: " + sbn);
             return null;
         }
         return entry;
@@ -1403,7 +1399,7 @@
                 entry.row.setVisibility(View.VISIBLE);
                 if (wasGone) {
                     // notify the scroller of a child addition
-                    mStackScroller.generateAddAnimation(entry.row);
+                    mStackScroller.generateAddAnimation(entry.row, true /* fromMoreCard */);
                 }
                 visibleNotifications++;
             }
@@ -1414,17 +1410,15 @@
         } else {
             mKeyguardIconOverflowContainer.setVisibility(View.GONE);
         }
-        // Move overflow container to second last position.
-        mStackScroller.changeViewPosition(mKeyguardIconOverflowContainer,
-                mStackScroller.getChildCount() - 2);
 
-        // Now move dismissView to the last position.
-        mStackScroller.changeViewPosition(mDismissView, mStackScroller.getChildCount() - 1);
+        mStackScroller.changeViewPosition(mKeyguardIconOverflowContainer,
+                mStackScroller.getChildCount() - 3);
+        mStackScroller.changeViewPosition(mDismissView, mStackScroller.getChildCount() - 2);
+        mStackScroller.changeViewPosition(mEmptyShadeView, mStackScroller.getChildCount() - 1);
     }
 
     private boolean shouldShowOnKeyguard(StatusBarNotification sbn) {
-        return mShowLockscreenNotifications &&
-                sbn.getNotification().priority >= Notification.PRIORITY_LOW;
+        return mShowLockscreenNotifications && !mNotificationData.isAmbient(sbn.getKey());
     }
 
     protected void setZenMode(int mode) {
@@ -1433,6 +1427,19 @@
         updateNotifications();
     }
 
+    // extended in PhoneStatusBar
+    protected void setShowLockscreenNotifications(boolean show) {
+        mShowLockscreenNotifications = show;
+    }
+
+    private void updateLockscreenNotificationSetting() {
+        final boolean show = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                1,
+                mCurrentUserId) != 0;
+        setShowLockscreenNotifications(show);
+    }
+
     protected abstract void haltTicker();
     protected abstract void setAreThereNotifications();
     protected abstract void updateNotifications();
@@ -1464,15 +1471,16 @@
 
         // XXX: modify when we do something more intelligent with the two content views
         final RemoteViews oldContentView = oldNotification.getNotification().contentView;
-        final RemoteViews contentView = notification.getNotification().contentView;
+        Notification n = notification.getNotification();
+        final RemoteViews contentView = n.contentView;
         final RemoteViews oldBigContentView = oldNotification.getNotification().bigContentView;
-        final RemoteViews bigContentView = notification.getNotification().bigContentView;
+        final RemoteViews bigContentView = n.bigContentView;
         final RemoteViews oldHeadsUpContentView = oldNotification.getNotification().headsUpContentView;
-        final RemoteViews headsUpContentView = notification.getNotification().headsUpContentView;
+        final RemoteViews headsUpContentView = n.headsUpContentView;
         final Notification oldPublicNotification = oldNotification.getNotification().publicVersion;
         final RemoteViews oldPublicContentView = oldPublicNotification != null
                 ? oldPublicNotification.contentView : null;
-        final Notification publicNotification = notification.getNotification().publicVersion;
+        final Notification publicNotification = n.publicVersion;
         final RemoteViews publicContentView = publicNotification != null
                 ? publicNotification.contentView : null;
 
@@ -1484,7 +1492,7 @@
                     + " bigContentView=" + oldBigContentView
                     + " publicView=" + oldPublicContentView
                     + " rowParent=" + oldEntry.row.getParent());
-            Log.d(TAG, "new notification: when=" + notification.getNotification().when
+            Log.d(TAG, "new notification: when=" + n.when
                     + " ongoing=" + oldNotification.isOngoing()
                     + " contentView=" + contentView
                     + " bigContentView=" + bigContentView
@@ -1521,8 +1529,8 @@
                         && oldPublicContentView.getPackage() != null
                         && oldPublicContentView.getPackage().equals(publicContentView.getPackage())
                         && oldPublicContentView.getLayoutId() == publicContentView.getLayoutId());
-        boolean updateTicker = notification.getNotification().tickerText != null
-                && !TextUtils.equals(notification.getNotification().tickerText,
+        boolean updateTicker = n.tickerText != null
+                && !TextUtils.equals(n.tickerText,
                 oldEntry.notification.getNotification().tickerText);
 
         final boolean shouldInterrupt = shouldInterrupt(notification);
@@ -1537,10 +1545,11 @@
                     // Update the icon
                     final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
                             notification.getUser(),
-                            notification.getNotification().icon,
-                            notification.getNotification().iconLevel,
-                            notification.getNotification().number,
-                            notification.getNotification().tickerText);
+                            n.icon,
+                            n.iconLevel,
+                            n.number,
+                            n.tickerText);
+                    oldEntry.icon.setNotification(n);
                     if (!oldEntry.icon.set(ic)) {
                         handleNotificationError(notification, "Couldn't update icon: " + ic);
                         return;
@@ -1607,10 +1616,11 @@
                     oldEntry.notification = notification;
                     final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
                             notification.getUser(),
-                            notification.getNotification().icon,
-                            notification.getNotification().iconLevel,
-                            notification.getNotification().number,
-                            notification.getNotification().tickerText);
+                            n.icon,
+                            n.iconLevel,
+                            n.number,
+                            n.tickerText);
+                    oldEntry.icon.setNotification(n);
                     oldEntry.icon.set(ic);
                     inflateViews(oldEntry, mStackScroller, wasHeadsUp);
                     mNotificationData.updateRanking(ranking);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index a82c907..63dd1e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -55,6 +55,8 @@
     private static final int MSG_SHOW_RECENT_APPS           = 14 << MSG_SHIFT;
     private static final int MSG_HIDE_RECENT_APPS           = 15 << MSG_SHIFT;
     private static final int MSG_BUZZ_BEEP_BLINKED          = 16 << MSG_SHIFT;
+    private static final int MSG_NOTIFICATION_LIGHT_OFF     = 17 << MSG_SHIFT;
+    private static final int MSG_NOTIFICATION_LIGHT_PULSE   = 18 << MSG_SHIFT;
 
     public static final int FLAG_EXCLUDE_NONE = 0;
     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -87,7 +89,7 @@
                 boolean showImeSwitcher);
         public void setHardKeyboardStatus(boolean available, boolean enabled);
         public void showRecentApps(boolean triggeredFromAltTab);
-        public void hideRecentApps(boolean triggeredFromAltTab);
+        public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
         public void toggleRecentApps();
         public void preloadRecentApps();
         public void cancelPreloadRecentApps();
@@ -95,6 +97,8 @@
         public void hideSearchPanel();
         public void setWindowState(int window, int state);
         public void buzzBeepBlinked();
+        public void notificationLightOff();
+        public void notificationLightPulse(int argb, int onMillis, int offMillis);
     }
 
     public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
@@ -187,11 +191,12 @@
         }
     }
 
-    public void hideRecentApps(boolean triggeredFromAltTab) {
+    public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
         synchronized (mList) {
             mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
             mHandler.obtainMessage(MSG_HIDE_RECENT_APPS,
-                    triggeredFromAltTab ? 1 : 0, 0, null).sendToTarget();
+                    triggeredFromAltTab ? 1 : 0, triggeredFromHomeKey ? 1 : 0,
+                    null).sendToTarget();
         }
     }
 
@@ -230,6 +235,19 @@
         }
     }
 
+    public void notificationLightOff() {
+        synchronized (mList) {
+            mHandler.sendEmptyMessage(MSG_NOTIFICATION_LIGHT_OFF);
+        }
+    }
+
+    public void notificationLightPulse(int argb, int onMillis, int offMillis) {
+        synchronized (mList) {
+            mHandler.obtainMessage(MSG_NOTIFICATION_LIGHT_PULSE, onMillis, offMillis, argb)
+                    .sendToTarget();
+        }
+    }
+
     private final class H extends Handler {
         public void handleMessage(Message msg) {
             final int what = msg.what & MSG_MASK;
@@ -289,7 +307,7 @@
                     mCallbacks.showRecentApps(msg.arg1 != 0);
                     break;
                 case MSG_HIDE_RECENT_APPS:
-                    mCallbacks.hideRecentApps(msg.arg1 != 0);
+                    mCallbacks.hideRecentApps(msg.arg1 != 0, msg.arg2 != 0);
                     break;
                 case MSG_TOGGLE_RECENT_APPS:
                     mCallbacks.toggleRecentApps();
@@ -306,7 +324,12 @@
                 case MSG_BUZZ_BEEP_BLINKED:
                     mCallbacks.buzzBeepBlinked();
                     break;
-
+                case MSG_NOTIFICATION_LIGHT_OFF:
+                    mCallbacks.notificationLightOff();
+                    break;
+                case MSG_NOTIFICATION_LIGHT_PULSE:
+                    mCallbacks.notificationLightPulse((Integer) msg.obj, msg.arg1, msg.arg2);
+                    break;
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
index d60c17f..897dbf2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
@@ -19,135 +19,21 @@
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.View;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import android.view.animation.PathInterpolator;
-import android.widget.Button;
-import android.widget.TextView;
+
 import com.android.systemui.R;
 
-public class DismissView extends ExpandableView {
-
-    private Button mClearAllText;
-    private boolean mIsVisible;
-    private boolean mAnimating;
-    private boolean mWillBeGone;
-
-    private final Interpolator mAppearInterpolator = new PathInterpolator(0f, 0.2f, 1f, 1f);
-    private final Interpolator mDisappearInterpolator = new PathInterpolator(0f, 0f, 0.8f, 1f);
+public class DismissView extends StackScrollerDecorView {
 
     public DismissView(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
     @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mClearAllText = (Button) findViewById(R.id.dismiss_text);
-        setInvisible();
+    protected View findContentView() {
+        return findViewById(R.id.dismiss_text);
     }
 
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-        setOutlineProvider(null);
-    }
-
-    @Override
-    public boolean isTransparent() {
-        return true;
-    }
-
-    public void performVisibilityAnimation(boolean nowVisible) {
-        animateText(nowVisible, null /* onFinishedRunnable */);
-    }
-
-    public void performVisibilityAnimation(boolean nowVisible, Runnable onFinishedRunnable) {
-        animateText(nowVisible, onFinishedRunnable);
-    }
-
-    public boolean isVisible() {
-        return mIsVisible || mAnimating;
-    }
-
-    /**
-     * Animate the text to a new visibility.
-     *
-     * @param nowVisible should it now be visible
-     * @param onFinishedRunnable A runnable which should be run when the animation is
-     *        finished.
-     */
-    private void animateText(boolean nowVisible, final Runnable onFinishedRunnable) {
-        if (nowVisible != mIsVisible) {
-            // Animate text
-            float endValue = nowVisible ? 1.0f : 0.0f;
-            Interpolator interpolator;
-            if (nowVisible) {
-                interpolator = mAppearInterpolator;
-            } else {
-                interpolator = mDisappearInterpolator;
-            }
-            mAnimating = true;
-            mClearAllText.animate()
-                    .alpha(endValue)
-                    .setInterpolator(interpolator)
-                    .setDuration(260)
-                    .withLayer()
-                    .withEndAction(new Runnable() {
-                        @Override
-                        public void run() {
-                            mAnimating = false;
-                            if (onFinishedRunnable != null) {
-                                onFinishedRunnable.run();
-                            }
-                        }
-                    });
-            mIsVisible = nowVisible;
-        } else {
-            if (onFinishedRunnable != null) {
-                onFinishedRunnable.run();
-            }
-        }
-    }
-
-    public void setInvisible() {
-        mClearAllText.setAlpha(0.0f);
-        mIsVisible = false;
-    }
-
-    @Override
-    public void performRemoveAnimation(float translationDirection, Runnable onFinishedRunnable) {
-        performVisibilityAnimation(false);
-    }
-
-    @Override
-    public void performAddAnimation(long delay) {
-        performVisibilityAnimation(true);
-    }
-
-    @Override
-    public void setScrimAmount(float scrimAmount) {
-        // We don't need to scrim the dismissView
-    }
-
-    public void setOnButtonClickListener(OnClickListener onClickListener) {
-        mClearAllText.setOnClickListener(onClickListener);
-    }
-
-    @Override
-    public boolean hasOverlappingRendering() {
-        return false;
-    }
-
-    public void cancelAnimation() {
-        mClearAllText.animate().cancel();
-    }
-
-    public boolean willBeGone() {
-        return mWillBeGone;
-    }
-
-    public void setWillBeGone(boolean willBeGone) {
-        mWillBeGone = willBeGone;
+    public void setOnButtonClickListener(OnClickListener listener) {
+        mContent.setOnClickListener(listener);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
index e9989ab..df475d5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
@@ -127,9 +127,7 @@
                 return true;
             case MotionEvent.ACTION_UP:
                 if (mDraggedFarEnough && mDragDownCallback.onDraggedDown(mStartingChild)) {
-                    if (mStartingChild != null) {
-                        mCallback.setUserLockedChild(mStartingChild, false);
-                    } else {
+                    if (mStartingChild == null) {
                         mDragDownCallback.setEmptyDragAmount(0f);
                     }
                     mDraggingDown = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
new file mode 100644
index 0000000..582d165
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.Interpolator;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
+
+public class EmptyShadeView extends StackScrollerDecorView {
+
+    public EmptyShadeView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected View findContentView() {
+        return findViewById(R.id.no_notifications);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 4b0af11..0960c00 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -37,6 +37,9 @@
     private boolean mUserLocked;
     /** Are we showing the "public" version */
     private boolean mShowingPublic;
+    private boolean mSensitive;
+    private boolean mShowingPublicInitialized;
+    private boolean mShowingPublicForIntrinsicHeight;
 
     /**
      * Is this notification expanded by the system. The expansion state can be overridden by the
@@ -78,6 +81,8 @@
         mHasUserChangedExpansion = false;
         mUserLocked = false;
         mShowingPublic = false;
+        mSensitive = false;
+        mShowingPublicInitialized = false;
         mIsSystemExpanded = false;
         mExpansionDisabled = false;
         mPublicLayout.reset();
@@ -222,7 +227,7 @@
             return mRowMinHeight;
         }
 
-        return mShowingPublic ? mRowMinHeight : getMaxExpandHeight();
+        return mShowingPublicForIntrinsicHeight ? mRowMinHeight : getMaxExpandHeight();
     }
 
     /**
@@ -248,17 +253,64 @@
         }
     }
 
-    public void setShowingPublic(boolean show) {
-        mShowingPublic = show;
+    public void setSensitive(boolean sensitive) {
+        mSensitive = sensitive;
+    }
+
+    public void setHideSensitiveForIntrinsicHeight(boolean hideSensitive) {
+        mShowingPublicForIntrinsicHeight = mSensitive && hideSensitive;
+    }
+
+    public void setHideSensitive(boolean hideSensitive, boolean animated, long delay,
+            long duration) {
+        boolean oldShowingPublic = mShowingPublic;
+        mShowingPublic = mSensitive && hideSensitive;
+        if (mShowingPublicInitialized && mShowingPublic == oldShowingPublic) {
+            return;
+        }
 
         // bail out if no public version
         if (mPublicLayout.getChildCount() == 0) return;
 
-        // TODO: animation?
-        mPublicLayout.setVisibility(show ? View.VISIBLE : View.GONE);
-        mPrivateLayout.setVisibility(show ? View.GONE : View.VISIBLE);
+        if (!animated) {
+            mPublicLayout.animate().cancel();
+            mPrivateLayout.animate().cancel();
+            mPublicLayout.setAlpha(1f);
+            mPrivateLayout.setAlpha(1f);
+            mPublicLayout.setVisibility(mShowingPublic ? View.VISIBLE : View.INVISIBLE);
+            mPrivateLayout.setVisibility(mShowingPublic ? View.INVISIBLE : View.VISIBLE);
+        } else {
+            animateShowingPublic(delay, duration);
+        }
 
         updateVetoButton();
+        mShowingPublicInitialized = true;
+    }
+
+    private void animateShowingPublic(long delay, long duration) {
+        final View source = mShowingPublic ? mPrivateLayout : mPublicLayout;
+        View target = mShowingPublic ? mPublicLayout : mPrivateLayout;
+        source.setVisibility(View.VISIBLE);
+        target.setVisibility(View.VISIBLE);
+        target.setAlpha(0f);
+        source.animate().cancel();
+        target.animate().cancel();
+        source.animate()
+                .alpha(0f)
+                .withLayer()
+                .setStartDelay(delay)
+                .setDuration(duration)
+                .withEndAction(new Runnable() {
+                    @Override
+                    public void run() {
+                        source.setVisibility(View.INVISIBLE);
+                    }
+                });
+        target.animate()
+                .alpha(1f)
+                .withLayer()
+                .setStartDelay(delay)
+                .setDuration(duration);
     }
 
     private void updateVetoButton() {
@@ -267,7 +319,7 @@
     }
 
     public int getMaxExpandHeight() {
-        return mShowingPublic ? mRowMinHeight : mMaxExpandHeight;
+        return mShowingPublicForIntrinsicHeight ? mRowMinHeight : mMaxExpandHeight;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index b71cd77..46d4a9a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -176,6 +176,23 @@
     }
 
     /**
+     * See {@link #setHideSensitive}. This is a variant which notifies this view in advance about
+     * the upcoming state of hiding sensitive notifications. It gets called at the very beginning
+     * of a stack scroller update such that the updated intrinsic height (which is dependent on
+     * whether private or public layout is showing) gets taken into account into all layout
+     * calculations.
+     */
+    public void setHideSensitiveForIntrinsicHeight(boolean hideSensitive) {
+    }
+
+    /**
+     * Sets whether the notification should hide its private contents if it is sensitive.
+     */
+    public void setHideSensitive(boolean hideSensitive, boolean animated, long delay,
+            long duration) {
+    }
+
+    /**
      * @return The desired notification height.
      */
     public int getIntrinsicHeight() {
@@ -220,6 +237,7 @@
     /**
      * Perform a remove animation on this view.
      *
+     * @param duration The duration of the remove animation.
      * @param translationDirection The direction value from [-1 ... 1] indicating in which the
      *                             animation should be performed. A value of -1 means that The
      *                             remove animation should be performed upwards,
@@ -227,10 +245,10 @@
      *                             Should mean the opposite.
      * @param onFinishedRunnable A runnable which should be run when the animation is finished.
      */
-    public abstract void performRemoveAnimation(float translationDirection,
+    public abstract void performRemoveAnimation(long duration, float translationDirection,
             Runnable onFinishedRunnable);
 
-    public abstract void performAddAnimation(long delay);
+    public abstract void performAddAnimation(long delay, long duration);
 
     public abstract void setScrimAmount(float scrimAmount);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
index 19bf121..6779e4e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -156,7 +156,6 @@
         drawBackgroundCircle(canvas);
         drawArrow(canvas);
         canvas.save();
-        updateIconColor();
         canvas.scale(mImageScale, mImageScale, getWidth() / 2, getHeight() / 2);
         super.onDraw(canvas);
         canvas.restore();
@@ -267,6 +266,7 @@
         if (!radiusNeedsAnimation) {
             if (mCircleAnimator == null) {
                 mCircleRadius = circleRadius;
+                updateIconColor();
                 invalidate();
                 if (nowHidden) {
                     if (mPreviewView != null) {
@@ -323,6 +323,7 @@
             @Override
             public void onAnimationUpdate(ValueAnimator animation) {
                 mCircleRadius = (float) animation.getAnimatedValue();
+                updateIconColor();
                 invalidate();
             }
         });
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java
index 451c5c5..edfd205 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java
@@ -38,6 +38,7 @@
         super.onFinishInflate();
         mIconsView = (NotificationOverflowIconsView) findViewById(R.id.overflow_icons_view);
         mIconsView.setMoreText((TextView) findViewById(R.id.more_text));
+        mIconsView.setOverflowIndicator(findViewById(R.id.more_icon_overflow));
     }
 
     public NotificationOverflowIconsView getIconsView() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
index dfeadc5..816612b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
@@ -76,23 +76,25 @@
         return true;
     }
 
-    public void performVisibilityAnimation(boolean nowVisible) {
-        animateDivider(nowVisible, null /* onFinishedRunnable */);
+    public void performVisibilityAnimation(boolean nowVisible, long delay) {
+        animateDivider(nowVisible, delay, null /* onFinishedRunnable */);
     }
 
     /**
      * Animate the divider to a new visibility.
      *
      * @param nowVisible should it now be visible
+     * @param delay the delay after the animation should start
      * @param onFinishedRunnable A runnable which should be run when the animation is
      *        finished.
      */
-    public void animateDivider(boolean nowVisible, Runnable onFinishedRunnable) {
+    public void animateDivider(boolean nowVisible, long delay, Runnable onFinishedRunnable) {
         if (nowVisible != mIsVisible) {
             // Animate dividers
             float endValue = nowVisible ? 1.0f : 0.0f;
             mLine.animate()
                     .alpha(endValue)
+                    .setStartDelay(delay)
                     .scaleX(endValue)
                     .scaleY(endValue)
                     .setInterpolator(mFastOutSlowInInterpolator)
@@ -113,13 +115,16 @@
     }
 
     @Override
-    public void performRemoveAnimation(float translationDirection, Runnable onFinishedRunnable) {
-        performVisibilityAnimation(false);
+    public void performRemoveAnimation(long duration, float translationDirection,
+            Runnable onFinishedRunnable) {
+        // TODO: Use duration
+        performVisibilityAnimation(false, 0 /* delay */);
     }
 
     @Override
-    public void performAddAnimation(long delay) {
-        performVisibilityAnimation(true);
+    public void performAddAnimation(long delay, long duration) {
+        // TODO: Use duration
+        performVisibilityAnimation(true, delay);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java
new file mode 100644
index 0000000..62a492e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.Interpolator;
+
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
+
+/**
+ * A common base class for all views in the notification stack scroller which don't have a
+ * background.
+ */
+public abstract class StackScrollerDecorView extends ExpandableView {
+
+    protected View mContent;
+    private boolean mIsVisible;
+    private boolean mAnimating;
+    private boolean mWillBeGone;
+
+    public StackScrollerDecorView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mContent = findContentView();
+        setInvisible();
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        setOutlineProvider(null);
+    }
+
+    @Override
+    public boolean isTransparent() {
+        return true;
+    }
+
+    public void performVisibilityAnimation(boolean nowVisible) {
+        animateText(nowVisible, null /* onFinishedRunnable */);
+    }
+
+    public void performVisibilityAnimation(boolean nowVisible, Runnable onFinishedRunnable) {
+        animateText(nowVisible, onFinishedRunnable);
+    }
+
+    public boolean isVisible() {
+        return mIsVisible || mAnimating;
+    }
+
+    /**
+     * Animate the text to a new visibility.
+     *
+     * @param nowVisible should it now be visible
+     * @param onFinishedRunnable A runnable which should be run when the animation is
+     *        finished.
+     */
+    private void animateText(boolean nowVisible, final Runnable onFinishedRunnable) {
+        if (nowVisible != mIsVisible) {
+            // Animate text
+            float endValue = nowVisible ? 1.0f : 0.0f;
+            Interpolator interpolator;
+            if (nowVisible) {
+                interpolator = PhoneStatusBar.ALPHA_IN;
+            } else {
+                interpolator = PhoneStatusBar.ALPHA_OUT;
+            }
+            mAnimating = true;
+            mContent.animate()
+                    .alpha(endValue)
+                    .setInterpolator(interpolator)
+                    .setDuration(260)
+                    .withLayer()
+                    .withEndAction(new Runnable() {
+                        @Override
+                        public void run() {
+                            mAnimating = false;
+                            if (onFinishedRunnable != null) {
+                                onFinishedRunnable.run();
+                            }
+                        }
+                    });
+            mIsVisible = nowVisible;
+        } else {
+            if (onFinishedRunnable != null) {
+                onFinishedRunnable.run();
+            }
+        }
+    }
+
+    public void setInvisible() {
+        mContent.setAlpha(0.0f);
+        mIsVisible = false;
+    }
+
+    @Override
+    public void performRemoveAnimation(long duration, float translationDirection,
+            Runnable onFinishedRunnable) {
+        // TODO: Use duration
+        performVisibilityAnimation(false);
+    }
+
+    @Override
+    public void performAddAnimation(long delay, long duration) {
+        // TODO: use delay and duration
+        performVisibilityAnimation(true);
+    }
+
+    @Override
+    public void setScrimAmount(float scrimAmount) {
+        // We don't need to scrim the dismissView
+    }
+
+    @Override
+    public boolean hasOverlappingRendering() {
+        return false;
+    }
+
+    public void cancelAnimation() {
+        mContent.animate().cancel();
+    }
+
+    public boolean willBeGone() {
+        return mWillBeGone;
+    }
+
+    public void setWillBeGone(boolean willBeGone) {
+        mWillBeGone = willBeGone;
+    }
+
+    protected abstract View findContentView();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 6f839bd..20dd3e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -57,8 +57,7 @@
         mNumberPain.setTextAlign(Paint.Align.CENTER);
         mNumberPain.setColor(res.getColor(R.drawable.notification_number_text_color));
         mNumberPain.setAntiAlias(true);
-        mNotification = notification;
-        setContentDescription(notification);
+        setNotification(notification);
 
         // We do not resize and scale system icons (on the right), only notification icons (on the
         // left).
@@ -73,6 +72,11 @@
         setScaleType(ImageView.ScaleType.CENTER);
     }
 
+    public void setNotification(Notification notification) {
+        mNotification = notification;
+        setContentDescription(notification);
+    }
+
     public StatusBarIconView(Context context, AttributeSet attrs) {
         super(context, attrs);
         final Resources res = context.getResources();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
index 303454b..152bfdc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
@@ -109,10 +109,6 @@
         mBarBackground.finishAnimation();
     }
 
-    public void setContentVisible(boolean visible) {
-        // for subclasses
-    }
-
     private static class BarBackgroundDrawable extends Drawable {
         private final int mOpaque;
         private final int mSemiTransparent;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
index 9cc559f..20ffba2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
@@ -98,7 +98,7 @@
 
     private void initDimens() {
         final ViewConfiguration configuration = ViewConfiguration.get(mContext);
-        mTouchSlop = configuration.getScaledTouchSlop();
+        mTouchSlop = configuration.getScaledPagingTouchSlop();
         mMinFlingVelocity = configuration.getScaledMinimumFlingVelocity();
         mMinTranslationAmount = mContext.getResources().getDimensionPixelSize(
                 R.dimen.keyguard_min_swipe_amount);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 82e59c0..79f9da4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -33,7 +33,6 @@
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityManager;
 import android.widget.FrameLayout;
-import android.widget.ImageView;
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
@@ -72,6 +71,8 @@
     private UnlockMethodCache mUnlockMethodCache;
     private LockPatternUtils mLockPatternUtils;
     private FlashlightController mFlashlightController;
+    private PreviewInflater mPreviewInflater;
+    private boolean mFaceUnlockRunning;
 
     public KeyguardBottomAreaView(Context context) {
         super(context);
@@ -105,9 +106,10 @@
         updatePhoneVisibility();
         mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
         mUnlockMethodCache.addListener(this);
-        updateTrust();
+        updateLockIcon();
         setClipChildren(false);
         setClipToPadding(false);
+        mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext));
         inflatePreviews();
     }
 
@@ -208,7 +210,8 @@
     public void launchCamera() {
         mFlashlightController.killFlashlight();
         Intent intent = getCameraIntent();
-        if (intent == SECURE_CAMERA_INTENT) {
+        if (intent == SECURE_CAMERA_INTENT &&
+                !mPreviewInflater.wouldLaunchResolverActivity(intent)) {
             mContext.startActivityAsUser(intent, UserHandle.CURRENT);
         } else {
             mActivityStarter.startActivity(intent);
@@ -224,21 +227,23 @@
     protected void onVisibilityChanged(View changedView, int visibility) {
         super.onVisibilityChanged(changedView, visibility);
         if (changedView == this && visibility == VISIBLE) {
-            updateTrust();
+            updateLockIcon();
             updateCameraVisibility();
         }
     }
 
-    private void updateTrust() {
+    private void updateLockIcon() {
         if (getVisibility() != VISIBLE) {
             return;
         }
-        int iconRes = mUnlockMethodCache.isMethodInsecure()
-                ? R.drawable.ic_lock_open_24dp
+        // TODO: Real icon for facelock.
+        int iconRes = mFaceUnlockRunning ? R.drawable.ic_account_circle
+                : mUnlockMethodCache.isMethodInsecure() ? R.drawable.ic_lock_open_24dp
                 : R.drawable.ic_lock_24dp;
         mLockIcon.setImageResource(iconRes);
         boolean trustManaged = mUnlockMethodCache.isTrustManaged();
-        mLockIcon.setBackgroundResource(trustManaged ? R.drawable.trust_circle : 0);
+        mLockIcon.setBackgroundResource(trustManaged && !mFaceUnlockRunning
+                ? R.drawable.trust_circle : 0);
     }
 
     public KeyguardAffordanceView getPhoneView() {
@@ -272,14 +277,13 @@
 
     @Override
     public void onMethodSecureChanged(boolean methodSecure) {
-        updateTrust();
+        updateLockIcon();
         updateCameraVisibility();
     }
 
     private void inflatePreviews() {
-        PreviewInflater inflater = new PreviewInflater(mContext, new LockPatternUtils(mContext));
-        mPhonePreview = inflater.inflatePreview(PHONE_INTENT);
-        mCameraPreview = inflater.inflatePreview(getCameraIntent());
+        mPhonePreview = mPreviewInflater.inflatePreview(PHONE_INTENT);
+        mCameraPreview = mPreviewInflater.inflatePreview(getCameraIntent());
         if (mPhonePreview != null) {
             mPreviewContainer.addView(mPhonePreview);
             mPhonePreview.setVisibility(View.INVISIBLE);
@@ -307,5 +311,11 @@
         public void onUserSwitchComplete(int userId) {
             updateCameraVisibility();
         }
+
+        @Override
+        public void onFaceUnlockStateChanged(boolean running) {
+            mFaceUnlockRunning = running;
+            updateLockIcon();
+        }
     };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index e6ffde0..8996197 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -47,7 +47,6 @@
     private StatusBarWindowManager mWindowManager;
     private KeyguardViewBase mKeyguardView;
     private ViewGroup mRoot;
-    private Interpolator mFadeOutInterpolator = new LinearInterpolator();
     private boolean mFadingOut;
 
     public KeyguardBouncer(Context context, ViewMediatorCallback callback,
@@ -101,7 +100,7 @@
 
                     // Make it disappear faster, as the focus should be on the activity behind.
                     .setDuration(duration / 2)
-                    .setInterpolator(mFadeOutInterpolator)
+                    .setInterpolator(PhoneStatusBar.ALPHA_OUT)
                     .setStartDelay(delay)
                     .withEndAction(new Runnable() {
                         @Override
@@ -109,7 +108,8 @@
                             mFadingOut = false;
                             hide(true /* destroyView */);
                         }
-                    });
+                    })
+                    .start();
         } else {
             hide(true /* destroyView */);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
index 3753a72..50ddeb3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
@@ -108,18 +108,6 @@
         return max;
     }
 
-    @Override
-    public void setContentVisible(boolean visible) {
-        final float alpha = visible ? 1 : 0;
-        fadeContent(mView.getBackButton(), alpha);
-    }
-
-    private void fadeContent(View v, float alpha) {
-        if (v != null) {
-            v.animate().alpha(alpha).setDuration(CONTENT_FADE_DURATION);
-        }
-    }
-
     private void setKeyButtonViewQuiescentAlpha(View button, float alpha, boolean animate) {
         if (button instanceof KeyButtonView) {
             ((KeyButtonView) button).setQuiescentAlpha(alpha, animate);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 21842bf..95cb9a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -88,6 +88,8 @@
     // performs manual animation in sync with layout transitions
     private final NavTransitionListener mTransitionListener = new NavTransitionListener();
 
+    private OnVerticalChangedListener mOnVerticalChangedListener;
+
     private class NavTransitionListener implements TransitionListener {
         private boolean mBackTransitioning;
         private boolean mHomeAppearing;
@@ -193,6 +195,10 @@
         mDelegateHelper.setBar(phoneStatusBar);
     }
 
+    public void setOnVerticalChangedListener(OnVerticalChangedListener onVerticalChangedListener) {
+        mOnVerticalChangedListener = onVerticalChangedListener;
+    }
+
     @Override
     public boolean onTouchEvent(MotionEvent event) {
         if (mDeadZone != null && event.getAction() == MotionEvent.ACTION_OUTSIDE) {
@@ -413,7 +419,7 @@
 
         // swap to x coordinate if orientation is not in vertical
         if (mDelegateHelper != null) {
-            mDelegateHelper.setSwapXY(!mVertical);
+            mDelegateHelper.setSwapXY(mVertical);
         }
 
         setNavigationIconHints(mNavigationIconHints, true);
@@ -435,6 +441,9 @@
             mVertical = newVertical;
             //Log.v(TAG, String.format("onSizeChanged: h=%d, w=%d, vert=%s", h, w, mVertical?"y":"n"));
             reorient();
+            if (mOnVerticalChangedListener != null) {
+                mOnVerticalChangedListener.onVerticalChanged(newVertical);
+            }
         }
 
         postCheckForInvalidLayout("sizeChanged");
@@ -542,4 +551,7 @@
         pw.println();
     }
 
+    public interface OnVerticalChangedListener {
+        void onVerticalChanged(boolean isVertical);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 602b914..6af2cf8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -31,6 +32,7 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
+import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
@@ -68,7 +70,8 @@
     private TextView mClockView;
     private View mReserveNotificationSpace;
     private MirrorView mSystemIconsCopy;
-
+    private View mQsNavbarScrim;
+    private View mNotificationContainerParent;
     private NotificationStackScrollLayout mNotificationStackScroller;
     private int mNotificationTopPadding;
     private boolean mAnimateNextTopPaddingChange;
@@ -78,6 +81,12 @@
     private boolean mQsTracking;
 
     /**
+     * Handles launching the secure camera properly even when other applications may be using the
+     * camera hardware.
+     */
+    private SecureCameraLaunchManager mSecureCameraLaunchManager;
+
+    /**
      * If set, the ongoing touch gesture might both trigger the expansion in {@link PanelView} and
      * the expansion for quick settings.
      */
@@ -92,6 +101,8 @@
     private boolean mQsExpandedWhenExpandingStarted;
     private boolean mQsFullyExpanded;
     private boolean mKeyguardShowing;
+    private boolean mDozing;
+    private boolean mKeyguardStatusBarTransparent;
     private int mStatusBarState;
     private float mInitialHeightOnTouch;
     private float mInitialTouchX;
@@ -139,7 +150,13 @@
     private boolean mIsLaunchTransitionRunning;
     private Runnable mLaunchAnimationEndRunnable;
     private boolean mOnlyAffordanceInThisMotion;
-    private boolean mKeyguardStatusBarAnimatingIn;
+    private boolean mKeyguardStatusViewAnimating;
+    private boolean mHeaderAnimatingIn;
+    private ObjectAnimator mQsContainerAnimator;
+
+    private boolean mShadeEmpty;
+
+    private boolean mQsScrimEnabled = true;
 
     public NotificationPanelView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -163,6 +180,7 @@
         mScrollView = (ObservableScrollView) findViewById(R.id.scroll_view);
         mScrollView.setListener(this);
         mReserveNotificationSpace = findViewById(R.id.reserve_notification_space);
+        mNotificationContainerParent = findViewById(R.id.notification_container_parent);
         mNotificationStackScroller = (NotificationStackScrollLayout)
                 findViewById(R.id.notification_stack_scroller);
         mNotificationStackScroller.setOnHeightChangedListener(this);
@@ -173,7 +191,10 @@
         mFastOutLinearInterpolator = AnimationUtils.loadInterpolator(getContext(),
                 android.R.interpolator.fast_out_linear_in);
         mKeyguardBottomArea = (KeyguardBottomAreaView) findViewById(R.id.keyguard_bottom_area);
+        mQsNavbarScrim = findViewById(R.id.qs_navbar_scrim);
         mAfforanceHelper = new KeyguardAffordanceHelper(this, getContext());
+        mSecureCameraLaunchManager =
+                new SecureCameraLaunchManager(getContext(), mKeyguardBottomArea);
     }
 
     @Override
@@ -193,6 +214,25 @@
                 getResources().getDimensionPixelSize(R.dimen.notification_scrim_wait_distance);
     }
 
+    public void updateResources() {
+        int panelWidth = getResources().getDimensionPixelSize(R.dimen.notification_panel_width);
+        int panelGravity = getResources().getInteger(R.integer.notification_panel_layout_gravity);
+        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mHeader.getLayoutParams();
+        if (lp.width != panelWidth) {
+            lp.width = panelWidth;
+            lp.gravity = panelGravity;
+            mHeader.setLayoutParams(lp);
+            mHeader.post(mUpdateHeader);
+        }
+
+        lp = (FrameLayout.LayoutParams) mNotificationContainerParent.getLayoutParams();
+        if (lp.width != panelWidth) {
+            lp.width = panelWidth;
+            lp.gravity = panelGravity;
+            mNotificationContainerParent.setLayoutParams(lp);
+        }
+    }
+
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
@@ -218,6 +258,16 @@
         }
     }
 
+    @Override
+    public void onAttachedToWindow() {
+        mSecureCameraLaunchManager.create();
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        mSecureCameraLaunchManager.destroy();
+    }
+
     /**
      * Positions the clock and notifications dynamically depending on how many notifications are
      * showing.
@@ -285,14 +335,16 @@
     }
 
     private void updateClock(float alpha, float scale) {
-        mKeyguardStatusView.setAlpha(alpha);
+        if (!mKeyguardStatusViewAnimating) {
+            mKeyguardStatusView.setAlpha(alpha);
+        }
         mKeyguardStatusView.setScaleX(scale);
         mKeyguardStatusView.setScaleY(scale);
     }
 
-    public void animateToFullShade() {
+    public void animateToFullShade(long delay) {
         mAnimateNextTopPaddingChange = true;
-        mNotificationStackScroller.goToFullShade();
+        mNotificationStackScroller.goToFullShade(delay);
         requestLayout();
     }
 
@@ -434,7 +486,13 @@
                 mIntercepting = false;
                 break;
         }
-        return !mQsExpanded && super.onInterceptTouchEvent(event);
+
+        // Allow closing the whole panel when in SHADE state.
+        if (mStatusBarState == StatusBarState.SHADE) {
+            return super.onInterceptTouchEvent(event);
+        } else {
+            return !mQsExpanded && super.onInterceptTouchEvent(event);
+        }
     }
 
     private void resetDownStates(MotionEvent event) {
@@ -487,7 +545,7 @@
             return true;
         }
         if (event.getActionMasked() == MotionEvent.ACTION_DOWN && getExpandedFraction() == 1f
-                && mStatusBar.getBarState() != StatusBarState.KEYGUARD) {
+                && mStatusBar.getBarState() != StatusBarState.KEYGUARD && !mQsExpanded) {
 
             // Down in the empty area while fully expanded - go to QS.
             mQsTracking = true;
@@ -500,7 +558,7 @@
         if (mExpandedHeight != 0) {
             handleQsDown(event);
         }
-        if (!mTwoFingerQsExpand && (mQsTracking || mQsExpanded)) {
+        if (!mTwoFingerQsExpand && mQsTracking) {
             onQsTouch(event);
             if (!mConflictingQsExpansionGesture) {
                 return true;
@@ -523,9 +581,15 @@
         return true;
     }
 
+    private boolean isInQsArea(float x, float y) {
+        return mStatusBarState != StatusBarState.SHADE
+                || y <= mNotificationStackScroller.getBottomMostNotificationBottom()
+                || y <= mQsContainer.getY() + mQsContainer.getHeight();
+    }
+
     private void handleQsDown(MotionEvent event) {
         if (event.getActionMasked() == MotionEvent.ACTION_DOWN
-                && shouldQuickSettingsIntercept(event.getX(), event.getY(), 0)) {
+                && shouldQuickSettingsIntercept(event.getX(), event.getY(), -1)) {
             mQsTracking = true;
             onQsExpansionStarted();
             mInitialHeightOnTouch = mQsExpansionHeight;
@@ -611,8 +675,9 @@
     }
 
     @Override
-    public void onOverscrolled(int amount) {
-        if (mIntercepting) {
+    public void onOverscrolled(float lastTouchX, float lastTouchY, int amount) {
+        if (mIntercepting && shouldQuickSettingsIntercept(lastTouchX, lastTouchY,
+                -1 /* yDiff: Not relevant here */)) {
             onQsExpansionStarted(amount);
             mInitialHeightOnTouch = mQsExpansionHeight;
             mInitialTouchY = mLastTouchY;
@@ -671,18 +736,191 @@
         }
     }
 
-    public void setBarState(int statusBarState) {
+    public void setBarState(int statusBarState, boolean keyguardFadingAway,
+            boolean goingToFullShade) {
         boolean keyguardShowing = statusBarState == StatusBarState.KEYGUARD
                 || statusBarState == StatusBarState.SHADE_LOCKED;
-        mKeyguardStatusBar.setAlpha(1f);
-        mKeyguardStatusBar.setVisibility(keyguardShowing ? View.VISIBLE : View.INVISIBLE);
         if (!mKeyguardShowing && keyguardShowing) {
             setQsTranslation(mQsExpansionHeight);
             mHeader.setTranslationY(0f);
         }
+        setKeyguardStatusViewVisibility(statusBarState, keyguardFadingAway, goingToFullShade);
+        setKeyguardBottomAreaVisibility(statusBarState, goingToFullShade);
+        if (goingToFullShade) {
+            animateKeyguardStatusBarOut();
+        } else {
+            mKeyguardStatusBar.setAlpha(1f);
+            mKeyguardStatusBar.setVisibility(keyguardShowing ? View.VISIBLE : View.INVISIBLE);
+        }
         mStatusBarState = statusBarState;
         mKeyguardShowing = keyguardShowing;
         updateQsState();
+        if (goingToFullShade) {
+            animateHeaderSlidingIn();
+        }
+    }
+
+    private final Runnable mAnimateKeyguardStatusViewInvisibleEndRunnable = new Runnable() {
+        @Override
+        public void run() {
+            mKeyguardStatusViewAnimating = false;
+            mKeyguardStatusView.setVisibility(View.GONE);
+        }
+    };
+
+    private final Runnable mAnimateKeyguardStatusViewVisibleEndRunnable = new Runnable() {
+        @Override
+        public void run() {
+            mKeyguardStatusViewAnimating = false;
+        }
+    };
+
+    private final Animator.AnimatorListener mAnimateHeaderSlidingInListener
+            = new AnimatorListenerAdapter() {
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            mHeaderAnimatingIn = false;
+            mQsContainerAnimator = null;
+            mQsContainer.removeOnLayoutChangeListener(mQsContainerAnimatorUpdater);
+        }
+    };
+
+    private final OnLayoutChangeListener mQsContainerAnimatorUpdater
+            = new OnLayoutChangeListener() {
+        @Override
+        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
+                int oldTop, int oldRight, int oldBottom) {
+            int oldHeight = oldBottom - oldTop;
+            int height = bottom - top;
+            if (height != oldHeight && mQsContainerAnimator != null) {
+                PropertyValuesHolder[] values = mQsContainerAnimator.getValues();
+                float newEndValue = mHeader.getCollapsedHeight() + mQsPeekHeight - height - top;
+                float newStartValue = -height - top;
+                values[0].setFloatValues(newStartValue, newEndValue);
+                mQsContainerAnimator.setCurrentPlayTime(mQsContainerAnimator.getCurrentPlayTime());
+            }
+        }
+    };
+
+    private final ViewTreeObserver.OnPreDrawListener mStartHeaderSlidingIn
+            = new ViewTreeObserver.OnPreDrawListener() {
+        @Override
+        public boolean onPreDraw() {
+            getViewTreeObserver().removeOnPreDrawListener(this);
+            mHeader.setTranslationY(-mHeader.getCollapsedHeight() - mQsPeekHeight);
+            mHeader.animate()
+                    .translationY(0f)
+                    .setStartDelay(mStatusBar.calculateGoingToFullShadeDelay())
+                    .setDuration(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE)
+                    .setInterpolator(mFastOutSlowInInterpolator)
+                    .start();
+            mQsContainer.setY(-mQsContainer.getHeight());
+            mQsContainerAnimator = ObjectAnimator.ofFloat(mQsContainer, View.TRANSLATION_Y,
+                    mQsContainer.getTranslationY(),
+                    mHeader.getCollapsedHeight() + mQsPeekHeight - mQsContainer.getHeight()
+                            - mQsContainer.getTop());
+            mQsContainerAnimator.setStartDelay(mStatusBar.calculateGoingToFullShadeDelay());
+            mQsContainerAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
+            mQsContainerAnimator.setInterpolator(mFastOutSlowInInterpolator);
+            mQsContainerAnimator.addListener(mAnimateHeaderSlidingInListener);
+            mQsContainerAnimator.start();
+            mQsContainer.addOnLayoutChangeListener(mQsContainerAnimatorUpdater);
+            return true;
+        }
+    };
+    
+    private void animateHeaderSlidingIn() {
+        mHeaderAnimatingIn = true;
+        getViewTreeObserver().addOnPreDrawListener(mStartHeaderSlidingIn);
+
+    }
+
+    private final Runnable mAnimateKeyguardStatusBarInvisibleEndRunnable = new Runnable() {
+        @Override
+        public void run() {
+            mKeyguardStatusBar.setVisibility(View.INVISIBLE);
+        }
+    };
+
+    private void animateKeyguardStatusBarOut() {
+        mKeyguardStatusBar.animate()
+                .alpha(0f)
+                .setStartDelay(mStatusBar.getKeyguardFadingAwayDelay())
+                .setDuration(mStatusBar.getKeyguardFadingAwayDuration()/2)
+                .setInterpolator(PhoneStatusBar.ALPHA_OUT)
+                .withEndAction(mAnimateKeyguardStatusBarInvisibleEndRunnable)
+                .start();
+    }
+
+    private final Runnable mAnimateKeyguardBottomAreaInvisibleEndRunnable = new Runnable() {
+        @Override
+        public void run() {
+            mKeyguardBottomArea.setVisibility(View.GONE);
+        }
+    };
+
+    private void setKeyguardBottomAreaVisibility(int statusBarState,
+            boolean goingToFullShade) {
+        if (goingToFullShade) {
+            mKeyguardBottomArea.animate().cancel();
+            mKeyguardBottomArea.animate()
+                    .alpha(0f)
+                    .setStartDelay(mStatusBar.getKeyguardFadingAwayDelay())
+                    .setDuration(mStatusBar.getKeyguardFadingAwayDuration()/2)
+                    .setInterpolator(PhoneStatusBar.ALPHA_OUT)
+                    .withEndAction(mAnimateKeyguardBottomAreaInvisibleEndRunnable)
+                    .start();
+        } else if (statusBarState == StatusBarState.KEYGUARD
+                || statusBarState == StatusBarState.SHADE_LOCKED) {
+            mKeyguardBottomArea.animate().cancel();
+            mKeyguardBottomArea.setVisibility(View.VISIBLE);
+            mKeyguardBottomArea.setAlpha(1f);
+        } else {
+            mKeyguardBottomArea.animate().cancel();
+            mKeyguardBottomArea.setVisibility(View.GONE);
+            mKeyguardBottomArea.setAlpha(1f);
+        }
+    }
+
+    private void setKeyguardStatusViewVisibility(int statusBarState, boolean keyguardFadingAway,
+            boolean goingToFullShade) {
+        if ((!keyguardFadingAway && mStatusBarState == StatusBarState.KEYGUARD
+                && statusBarState != StatusBarState.KEYGUARD) || goingToFullShade) {
+            mKeyguardStatusView.animate().cancel();
+            mKeyguardStatusViewAnimating = true;
+            mKeyguardStatusView.animate()
+                    .alpha(0f)
+                    .setStartDelay(0)
+                    .setDuration(160)
+                    .setInterpolator(PhoneStatusBar.ALPHA_OUT)
+                    .withEndAction(mAnimateKeyguardStatusViewInvisibleEndRunnable);
+            if (keyguardFadingAway) {
+                mKeyguardStatusView.animate()
+                        .setStartDelay(mStatusBar.getKeyguardFadingAwayDelay())
+                        .setDuration(mStatusBar.getKeyguardFadingAwayDuration()/2)
+                        .start();
+            }
+        } else if (mStatusBarState == StatusBarState.SHADE_LOCKED
+                && statusBarState == StatusBarState.KEYGUARD) {
+            mKeyguardStatusView.animate().cancel();
+            mKeyguardStatusView.setVisibility(View.VISIBLE);
+            mKeyguardStatusViewAnimating = true;
+            mKeyguardStatusView.setAlpha(0f);
+            mKeyguardStatusView.animate()
+                    .alpha(1f)
+                    .setStartDelay(0)
+                    .setDuration(320)
+                    .setInterpolator(PhoneStatusBar.ALPHA_IN)
+                    .withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable);
+        } else if (statusBarState == StatusBarState.KEYGUARD) {
+            mKeyguardStatusView.animate().cancel();
+            mKeyguardStatusView.setVisibility(View.VISIBLE);
+            mKeyguardStatusView.setAlpha(1f);
+        } else {
+            mKeyguardStatusView.animate().cancel();
+            mKeyguardStatusView.setVisibility(View.GONE);
+            mKeyguardStatusView.setAlpha(1f);
+        }
     }
 
     private void updateQsState() {
@@ -696,6 +934,11 @@
         mQsContainer.setVisibility(
                 mKeyguardShowing && !expandVisually ? View.INVISIBLE : View.VISIBLE);
         mScrollView.setTouchEnabled(mQsExpanded);
+        updateEmptyShadeView();
+        mQsNavbarScrim.setVisibility(mStatusBarState == StatusBarState.SHADE && mQsExpanded
+                && !mStackScrollerOverscrolling && mQsScrimEnabled
+                        ? View.VISIBLE
+                        : View.INVISIBLE);
     }
 
     private void setQsExpansion(float height) {
@@ -716,13 +959,16 @@
             alpha *= 2;
             alpha = Math.min(1, alpha);
             alpha = 1 - alpha;
-            if (alpha == 0f) {
-                mKeyguardStatusBar.setVisibility(View.INVISIBLE);
-            } else {
-                mKeyguardStatusBar.setVisibility(View.VISIBLE);
+            mKeyguardStatusBarTransparent = alpha == 0f;
+            updateKeyguardStatusBarVisibility();
+            if (!mKeyguardStatusBarTransparent) {
                 mKeyguardStatusBar.setAlpha(alpha);
             }
         }
+        if (mStatusBarState == StatusBarState.SHADE && mQsExpanded
+                && !mStackScrollerOverscrolling && mQsScrimEnabled) {
+            mQsNavbarScrim.setAlpha(getQsExpansionFraction());
+        }
     }
 
     private void updateNotificationScrim(float height) {
@@ -741,7 +987,9 @@
     }
 
     private void setQsTranslation(float height) {
-        mQsContainer.setY(height - mQsContainer.getHeight() + getHeaderTranslation());
+        if (!mHeaderAnimatingIn) {
+            mQsContainer.setY(height - mQsContainer.getHeight() + getHeaderTranslation());
+        }
         if (mKeyguardShowing) {
             mHeader.setY(interpolate(getQsExpansionFraction(), -mHeader.getHeight(), 0));
         }
@@ -838,7 +1086,7 @@
         boolean onHeader = x >= header.getLeft() && x <= header.getRight()
                 && y >= header.getTop() && y <= header.getBottom();
         if (mQsExpanded) {
-            return onHeader || (mScrollView.isScrolledToBottom() && yDiff < 0);
+            return onHeader || (mScrollView.isScrolledToBottom() && yDiff < 0) && isInQsArea(x, y);
         } else {
             return onHeader;
         }
@@ -888,8 +1136,9 @@
         }
         if (!isInSettings()) {
             return mNotificationStackScroller.isScrolledToBottom();
+        } else {
+            return mScrollView.isScrolledToBottom();
         }
-        return super.isScrolledToBottom();
     }
 
     @Override
@@ -1039,7 +1288,9 @@
     }
 
     private void updateHeaderShade() {
-        mHeader.setTranslationY(getHeaderTranslation());
+        if (!mHeaderAnimatingIn) {
+            mHeader.setTranslationY(getHeaderTranslation());
+        }
         setQsTranslation(mQsExpansionHeight);
     }
 
@@ -1076,7 +1327,7 @@
         }
         alpha = Math.max(0, Math.min(alpha, 1));
         alpha = (float) Math.pow(alpha, 0.75);
-        if (!mQsExpanded && !mKeyguardStatusBarAnimatingIn) {
+        if (!mQsExpanded) {
             mKeyguardStatusBar.setAlpha(alpha);
         }
         mKeyguardBottomArea.setAlpha(alpha);
@@ -1153,6 +1404,9 @@
                 || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
             mAfforanceHelper.animateHideLeftRightIcon();
         }
+        if (mQsExpanded) {
+            mTwoFingerQsExpand = true;
+        }
     }
 
     @Override
@@ -1221,7 +1475,7 @@
         if (start) {
             mKeyguardBottomArea.launchPhone();
         } else {
-            mKeyguardBottomArea.launchCamera();
+            mSecureCameraLaunchManager.startSecureCameraLaunch();
         }
         mBlockTouches = true;
     }
@@ -1286,6 +1540,7 @@
 
     @Override
     public void onSwipingStarted() {
+        mSecureCameraLaunchManager.onSwipingStarted();
         requestDisallowInterceptTouchEvent(true);
         mOnlyAffordanceInThisMotion = true;
     }
@@ -1374,6 +1629,14 @@
         return mQsExpanded;
     }
 
+    public boolean isQsDetailShowing() {
+        return mQsPanel.isShowingDetail();
+    }
+
+    public void closeQsDetail() {
+        mQsPanel.closeDetail();
+    }
+
     @Override
     public boolean shouldDelayChildPressedState() {
         return true;
@@ -1405,4 +1668,46 @@
     private static float interpolate(float t, float start, float end) {
         return (1 - t) * start + t * end;
     }
+
+    private void updateKeyguardStatusBarVisibility() {
+        mKeyguardStatusBar.setVisibility(mKeyguardShowing && !mKeyguardStatusBarTransparent
+                && !mDozing ? VISIBLE : INVISIBLE);
+    }
+
+    public void setDozing(boolean dozing) {
+        if (dozing == mDozing) return;
+        mDozing = dozing;
+        if (mDozing) {
+            setBackgroundColor(0xff000000);
+        } else {
+            setBackground(null);
+        }
+        updateKeyguardStatusBarVisibility();
+    }
+
+    public void setShadeEmpty(boolean shadeEmpty) {
+        mShadeEmpty = shadeEmpty;
+        updateEmptyShadeView();
+    }
+
+    private void updateEmptyShadeView() {
+
+        // Hide "No notifications" in QS.
+        mNotificationStackScroller.updateEmptyShadeView(mShadeEmpty && !mQsExpanded);
+    }
+
+    public void setQsScrimEnabled(boolean qsScrimEnabled) {
+        boolean changed = mQsScrimEnabled != qsScrimEnabled;
+        mQsScrimEnabled = qsScrimEnabled;
+        if (changed) {
+            updateQsState();
+        }
+    }
+
+    private final Runnable mUpdateHeader = new Runnable() {
+        @Override
+        public void run() {
+            mHeader.updateEverything();
+        }
+    };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
index 5920580..ee6b1a9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
@@ -31,6 +31,8 @@
     private int mLastOverscrollAmount;
     private boolean mTouchEnabled = true;
     private boolean mHandlingTouchEvent;
+    private float mLastX;
+    private float mLastY;
 
     public ObservableScrollView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -65,6 +67,8 @@
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
         mHandlingTouchEvent = true;
+        mLastX = ev.getX();
+        mLastY = ev.getY();
         boolean result = super.onTouchEvent(ev);
         mHandlingTouchEvent = false;
         return result;
@@ -73,6 +77,8 @@
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         mHandlingTouchEvent = true;
+        mLastX = ev.getX();
+        mLastY = ev.getY();
         boolean result = super.onInterceptTouchEvent(ev);
         mHandlingTouchEvent = false;
         return result;
@@ -107,12 +113,12 @@
     protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
         super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
         if (mListener != null && mLastOverscrollAmount > 0) {
-            mListener.onOverscrolled(mLastOverscrollAmount);
+            mListener.onOverscrolled(mLastX, mLastY, mLastOverscrollAmount);
         }
     }
 
     public interface Listener {
         void onScrollChanged();
-        void onOverscrolled(int amount);
+        void onOverscrolled(float lastX, float lastY, int amount);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 3ec2395..469a831 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -501,31 +501,11 @@
             @Override
             public void onAnimationEnd(Animator animation) {
                 if (clearAllExpandHack && !mCancelled) {
-                    mHeightAnimator = createHeightAnimator(getMaxPanelHeight());
-                    mHeightAnimator.setInterpolator(mLinearOutSlowInInterpolator);
-                    mHeightAnimator.setDuration(350);
-                    mHeightAnimator.addListener(new AnimatorListenerAdapter() {
-                        private boolean mCancelled;
-
-                        @Override
-                        public void onAnimationCancel(Animator animation) {
-                            mCancelled = true;
-                        }
-
-                        @Override
-                        public void onAnimationEnd(Animator animation) {
-                            mHeightAnimator = null;
-                            if (!mCancelled) {
-                                notifyExpandingFinished();
-                            }
-                        }
-                    });
-                    mHeightAnimator.start();
-                } else {
-                    mHeightAnimator = null;
-                    if (!mCancelled) {
-                        notifyExpandingFinished();
-                    }
+                    setExpandedHeightInternal(getMaxPanelHeight());
+                }
+                mHeightAnimator = null;
+                if (!mCancelled) {
+                    notifyExpandingFinished();
                 }
             }
         });
@@ -873,6 +853,12 @@
         }
     }
 
+    private final Runnable mPostCollapseRunnable = new Runnable() {
+        @Override
+        public void run() {
+            collapse();
+        }
+    };
     private boolean onMiddleClicked() {
         switch (mStatusBar.getBarState()) {
             case StatusBarState.KEYGUARD:
@@ -882,7 +868,10 @@
                 mStatusBar.goToKeyguard();
                 return true;
             case StatusBarState.SHADE:
-                collapse();
+
+                // This gets called in the middle of the touch handling, where the state is still
+                // that we are tracking the panel. Collapse the panel after this is done.
+                post(mPostCollapseRunnable);
                 return false;
             default:
                 return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 1661af4..015a21d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -22,7 +22,6 @@
 import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
 import static android.app.StatusBarManager.windowStateToString;
-import static com.android.keyguard.KeyguardHostView.OnDismissAction;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
@@ -106,6 +105,7 @@
 import android.widget.TextView;
 
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.keyguard.KeyguardHostView.OnDismissAction;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.DemoMode;
 import com.android.systemui.EventLogTags;
@@ -119,6 +119,7 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DismissView;
 import com.android.systemui.statusbar.DragDownHelper;
+import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.GestureRecorder;
 import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -129,20 +130,21 @@
 import com.android.systemui.statusbar.SpeedBumpView;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.policy.NextAlarmController;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
 import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
 import com.android.systemui.statusbar.policy.CastControllerImpl;
 import com.android.systemui.statusbar.policy.FlashlightController;
 import com.android.systemui.statusbar.policy.HeadsUpNotificationView;
+import com.android.systemui.statusbar.policy.HotspotControllerImpl;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
-import com.android.systemui.statusbar.policy.HotspotControllerImpl;
-import com.android.systemui.statusbar.policy.UserInfoController;
 import com.android.systemui.statusbar.policy.LocationControllerImpl;
 import com.android.systemui.statusbar.policy.NetworkControllerImpl;
+import com.android.systemui.statusbar.policy.NextAlarmController;
 import com.android.systemui.statusbar.policy.RotationLockControllerImpl;
+import com.android.systemui.statusbar.policy.SecurityControllerImpl;
+import com.android.systemui.statusbar.policy.UserInfoController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
@@ -212,6 +214,7 @@
 
     // These are no longer handled by the policy, because we need custom strategies for them
     BluetoothControllerImpl mBluetoothController;
+    SecurityControllerImpl mSecurityController;
     BatteryController mBatteryController;
     LocationControllerImpl mLocationController;
     NetworkControllerImpl mNetworkController;
@@ -364,7 +367,8 @@
         @Override
         public void onChange(boolean selfChange) {
             boolean wasUsing = mUseHeadsUp;
-            mUseHeadsUp = ENABLE_HEADS_UP && Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
+            mUseHeadsUp = ENABLE_HEADS_UP && !mDisableNotificationAlerts
+                    && Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
                     mContext.getContentResolver(), Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
                     Settings.Global.HEADS_UP_OFF);
             mHeadsUpTicker = mUseHeadsUp && 0 != Settings.Global.getInt(
@@ -455,6 +459,7 @@
     private int mDrawCount;
     private Runnable mLaunchTransitionEndRunnable;
     private boolean mLaunchTransitionFadingAway;
+    private ExpandableNotificationRow mDraggedDownRow;
 
     private static final int VISIBLE_LOCATIONS = ViewState.LOCATION_FIRST_CARD
             | ViewState.LOCATION_TOP_STACK_PEEKING
@@ -638,6 +643,16 @@
 
                 mNavigationBarView.setDisabledFlags(mDisabled);
                 mNavigationBarView.setBar(this);
+                mNavigationBarView.setOnVerticalChangedListener(
+                        new NavigationBarView.OnVerticalChangedListener() {
+                    @Override
+                    public void onVerticalChanged(boolean isVertical) {
+                        if (mSearchPanelView != null) {
+                            mSearchPanelView.setHorizontal(isVertical);
+                        }
+                        mNotificationPanel.setQsScrimEnabled(!isVertical);
+                    }
+                });
                 mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
                     @Override
                     public boolean onTouch(View v, MotionEvent event) {
@@ -684,6 +699,9 @@
             }
         });
         mStackScroller.setDismissView(mDismissView);
+        mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
+                R.layout.status_bar_no_notifications, mStackScroller, false);
+        mStackScroller.setEmptyShadeView(mEmptyShadeView);
         mExpandedContents = mStackScroller;
 
         mScrimController = new ScrimController(mStatusBarWindow.findViewById(R.id.scrim_behind),
@@ -735,6 +753,7 @@
         mNetworkController = new NetworkControllerImpl(mContext);
         mHotspotController = new HotspotControllerImpl(mContext);
         mBluetoothController = new BluetoothControllerImpl(mContext);
+        mSecurityController = new SecurityControllerImpl(mContext);
         if (mContext.getResources().getBoolean(R.bool.config_showRotationLock)) {
             mRotationLockController = new RotationLockControllerImpl(mContext);
         }
@@ -796,7 +815,8 @@
                     mBluetoothController, mLocationController, mRotationLockController,
                     mNetworkController, mZenModeController, mHotspotController,
                     mCastController, mFlashlightController,
-                    mUserSwitcherController, mKeyguardMonitor);
+                    mUserSwitcherController, mKeyguardMonitor,
+                    mSecurityController);
             mQSPanel.setHost(qsh);
             for (QSTile<?> tile : qsh.getTiles()) {
                 mQSPanel.addTile(tile);
@@ -946,20 +966,6 @@
     }
 
     @Override
-    protected void onShowSearchPanel() {
-        if (mNavigationBarView != null) {
-            mNavigationBarView.getBarTransitions().setContentVisible(false);
-        }
-    }
-
-    @Override
-    protected void onHideSearchPanel() {
-        if (mNavigationBarView != null) {
-            mNavigationBarView.getBarTransitions().setContentVisible(true);
-        }
-    }
-
-    @Override
     protected View getStatusBarView() {
         return mStatusBarView;
     }
@@ -984,8 +990,6 @@
         }
         lp.gravity = Gravity.BOTTOM | Gravity.START;
         lp.setTitle("SearchPanel");
-        // TODO: Define custom animation for Search panel
-        lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
         lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
         | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
         return lp;
@@ -1061,7 +1065,7 @@
     View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
         public boolean onTouch(View v, MotionEvent event) {
             switch(event.getAction()) {
-            case MotionEvent.ACTION_DOWN:
+                case MotionEvent.ACTION_DOWN:
                 if (!shouldDisableNavbarGestures()) {
                     mHandler.removeCallbacks(mShowSearchPanel);
                     mHandler.postDelayed(mShowSearchPanel, mShowSearchHoldoff);
@@ -1361,10 +1365,15 @@
             int vis = ent.notification.getNotification().visibility;
 
             // Display public version of the notification if we need to redact.
-            final boolean hideSensitive = shouldHideSensitiveContents(ent.notification.getUserId());
-            boolean showingPublic = vis == Notification.VISIBILITY_PRIVATE && hideSensitive;
-            ent.row.setShowingPublic(showingPublic);
+            final boolean hideSensitive =
+                    !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId());
+            boolean sensitive = vis == Notification.VISIBILITY_PRIVATE;
+            boolean showingPublic = sensitive && hideSensitive && isLockscreenPublicMode();
+            ent.row.setSensitive(sensitive && hideSensitive);
             if (ent.autoRedacted && ent.legacy) {
+
+                // TODO: Also fade this? Or, maybe easier (and better), provide a dark redacted form
+                // for legacy auto redacted notifications.
                 if (showingPublic) {
                     ent.row.setShowingLegacyBackground(false);
                 } else {
@@ -1417,6 +1426,7 @@
         updateRowStates();
         updateSpeedbump();
         updateClearAll();
+        updateEmptyShadeView();
 
         mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned() && mUserSetup);
         mShadeUpdates.check();
@@ -1429,6 +1439,13 @@
         mStackScroller.updateDismissView(showDismissView);
     }
 
+    private void updateEmptyShadeView() {
+        boolean showEmptyShade =
+                mState != StatusBarState.KEYGUARD &&
+                        mNotificationData.getActiveNotifications().size() == 0;
+        mNotificationPanel.setShadeEmpty(showEmptyShade);
+    }
+
     private void updateSpeedbump() {
         int speedbumpIndex = -1;
         int currentIndex = 0;
@@ -1915,6 +1932,12 @@
                 animateStatusBarShow(mNotificationIconArea, animate);
             }
         }
+
+        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
+            mDisableNotificationAlerts =
+                    (state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
+            mHeadsUpObserver.onChange(true);
+        }
     }
 
     /**
@@ -2107,8 +2130,10 @@
         }
 
         if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
-            mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
-            mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
+            if (!mHandler.hasMessages(MSG_HIDE_RECENT_APPS)) {
+                mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
+                mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
+            }
         }
 
         if ((flags & CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL) == 0) {
@@ -2326,6 +2351,20 @@
         }
     }
 
+    @Override
+    public void notificationLightOff() {
+        if (mDozeServiceHost != null) {
+            mDozeServiceHost.fireNotificationLight(false);
+        }
+    }
+
+    @Override
+    public void notificationLightPulse(int argb, int onMillis, int offMillis) {
+        if (mDozeServiceHost != null) {
+            mDozeServiceHost.fireNotificationLight(true);
+        }
+    }
+
     @Override // CommandQueue
     public void setSystemUiVisibility(int vis, int mask) {
         final int oldVal = mSystemUiVisibility;
@@ -2436,7 +2475,7 @@
         final boolean powerSave = mBatteryController.isPowerSave();
         final boolean anim = (mScreenOn == null || mScreenOn) && windowState != WINDOW_STATE_HIDDEN
                 && !powerSave;
-        if (powerSave && getBarState() != StatusBarState.KEYGUARD) {
+        if (powerSave && getBarState() == StatusBarState.SHADE) {
             mode = MODE_WARNING;
         }
         transitions.transitionTo(mode, anim);
@@ -2708,7 +2747,7 @@
         pw.print("  mMediaMetadata=");
         pw.print(mMediaMetadata);
         if (mMediaMetadata != null) {
-            pw.print(" title=" + mMediaMetadata.getString(MediaMetadata.METADATA_KEY_TITLE));
+            pw.print(" title=" + mMediaMetadata.getText(MediaMetadata.METADATA_KEY_TITLE));
         }
         pw.println();
 
@@ -2770,6 +2809,9 @@
         if (mNextAlarmController != null) {
             mNextAlarmController.dump(fd, pw, args);
         }
+        if (mSecurityController != null) {
+            mSecurityController.dump(fd, pw, args);
+        }
     }
 
     private String hunStateToString(Entry entry) {
@@ -2988,11 +3030,20 @@
      */
     void updateResources() {
         // Update the quick setting tiles
-        if (mQSPanel != null) mQSPanel.updateResources();
+        if (mQSPanel != null) {
+            mQSPanel.updateResources();
+        }
 
         loadDimens();
         mLinearOutSlowIn = AnimationUtils.loadInterpolator(
                 mContext, android.R.interpolator.linear_out_slow_in);
+
+        if (mNotificationPanel != null) {
+            mNotificationPanel.updateResources();
+        }
+        if (mHeadsUpNotificationView != null) {
+            mHeadsUpNotificationView.updateResources();
+        }
     }
 
     protected void loadDimens() {
@@ -3034,7 +3085,7 @@
 
         mKeyguardMaxNotificationCount = res.getInteger(R.integer.keyguard_max_notification_count);
 
-        if (false) Log.v(TAG, "updateResources");
+        if (DEBUG) Log.v(TAG, "updateResources");
     }
 
     // Visibility reporting
@@ -3290,9 +3341,14 @@
 
     public void showKeyguard() {
         setBarState(StatusBarState.KEYGUARD);
-        updateKeyguardState();
+        updateKeyguardState(false /* goingToFullShade */);
         instantExpandNotificationsPanel();
         mLeaveOpenOnKeyguardHide = false;
+        if (mDraggedDownRow != null) {
+            mDraggedDownRow.setUserLocked(false);
+            mDraggedDownRow.notifyHeightChanged();
+            mDraggedDownRow = null;
+        }
     }
 
     public boolean isInLaunchTransition() {
@@ -3341,15 +3397,28 @@
         }
     }
 
-    public void hideKeyguard() {
+    /**
+     * @return true if we would like to stay in the shade, false if it should go away entirely
+     */
+    public boolean hideKeyguard() {
+        boolean staying = mLeaveOpenOnKeyguardHide;
         setBarState(StatusBarState.SHADE);
         if (mLeaveOpenOnKeyguardHide) {
             mLeaveOpenOnKeyguardHide = false;
-            mNotificationPanel.animateToFullShade();
+            mNotificationPanel.animateToFullShade(calculateGoingToFullShadeDelay());
+            if (mDraggedDownRow != null) {
+                mDraggedDownRow.setUserLocked(false);
+                mDraggedDownRow = null;
+            }
         } else {
             instantCollapseNotificationPanel();
         }
-        updateKeyguardState();
+        updateKeyguardState(staying);
+        return staying;
+    }
+
+    public long calculateGoingToFullShadeDelay() {
+        return mKeyguardFadingAwayDelay + mKeyguardFadingAwayDuration;
     }
 
     /**
@@ -3380,28 +3449,24 @@
                 && mStatusBarKeyguardViewManager.isSecure());
     }
 
-    private void updateKeyguardState() {
+    private void updateKeyguardState(boolean goingToFullShade) {
         if (mState == StatusBarState.KEYGUARD) {
-            mKeyguardStatusView.setVisibility(View.VISIBLE);
             mKeyguardIndicationController.setVisible(true);
             mNotificationPanel.resetViews();
             mKeyguardUserSwitcher.setKeyguard(true);
         } else {
-            mKeyguardStatusView.setVisibility(View.GONE);
             mKeyguardIndicationController.setVisible(false);
             mKeyguardUserSwitcher.setKeyguard(false);
         }
         if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
-            mKeyguardBottomArea.setVisibility(View.VISIBLE);
             mScrimController.setKeyguardShowing(true);
         } else {
-            mKeyguardBottomArea.setVisibility(View.GONE);
             mScrimController.setKeyguardShowing(false);
         }
-        mNotificationPanel.setBarState(mState);
+        mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
         updateDozingState();
-        updateStackScrollerState();
         updatePublicMode();
+        updateStackScrollerState(goingToFullShade);
         updateNotifications();
         checkBarModes();
         updateCarrierLabelVisibility(false);
@@ -3414,23 +3479,21 @@
         if (mState != StatusBarState.KEYGUARD) {
             return;
         }
+        mNotificationPanel.setDozing(mDozing);
         if (mDozing) {
-            mNotificationPanel.setBackgroundColor(0xff000000);
-            mKeyguardStatusBar.setVisibility(View.INVISIBLE);
             mKeyguardBottomArea.setVisibility(View.INVISIBLE);
             mStackScroller.setDark(true, false /*animate*/);
         } else {
-            mNotificationPanel.setBackground(null);
-            mKeyguardStatusBar.setVisibility(View.VISIBLE);
-                mKeyguardBottomArea.setVisibility(View.VISIBLE);
+            mKeyguardBottomArea.setVisibility(View.VISIBLE);
             mStackScroller.setDark(false, false /*animate*/);
         }
         mScrimController.setDozing(mDozing);
     }
 
-    public void updateStackScrollerState() {
+    public void updateStackScrollerState(boolean goingToFullShade) {
         if (mStackScroller == null) return;
         boolean onKeyguard = mState == StatusBarState.KEYGUARD;
+        mStackScroller.setHideSensitive(isLockscreenPublicMode(), goingToFullShade);
         mStackScroller.setDimmed(onKeyguard, false /* animate */);
         mStackScroller.setExpandingEnabled(!onKeyguard);
         ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild();
@@ -3460,7 +3523,11 @@
             return true;
         }
         if (mNotificationPanel.isQsExpanded()) {
-            mNotificationPanel.animateCloseQs();
+            if (mNotificationPanel.isQsDetailShowing()) {
+                mNotificationPanel.closeQsDetail();
+            } else {
+                mNotificationPanel.animateCloseQs();
+            }
             return true;
         }
         if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED) {
@@ -3607,17 +3674,22 @@
      * @param expandView The view to expand after going to the shade.
      */
     public void goToLockedShade(View expandView) {
+        ExpandableNotificationRow row = null;
         if (expandView instanceof ExpandableNotificationRow) {
-            ExpandableNotificationRow row = (ExpandableNotificationRow) expandView;
+            row = (ExpandableNotificationRow) expandView;
             row.setUserExpanded(true);
         }
         if (isLockscreenPublicMode() && !userAllowsPrivateNotificationsInPublic(mCurrentUserId)) {
             mLeaveOpenOnKeyguardHide = true;
             showBouncer();
+            mDraggedDownRow = row;
         } else {
-            mNotificationPanel.animateToFullShade();
+            mNotificationPanel.animateToFullShade(0 /* delay */);
             setBarState(StatusBarState.SHADE_LOCKED);
-            updateKeyguardState();
+            updateKeyguardState(false /* goingToFullShade */);
+            if (row != null) {
+                row.setUserLocked(false);
+            }
         }
     }
 
@@ -3627,7 +3699,7 @@
     public void goToKeyguard() {
         if (mState == StatusBarState.SHADE_LOCKED) {
             setBarState(StatusBarState.KEYGUARD);
-            updateKeyguardState();
+            updateKeyguardState(false /* goingToFullShade */);
         }
     }
 
@@ -3638,6 +3710,14 @@
         return mNotificationPanel;
     }
 
+    public long getKeyguardFadingAwayDelay() {
+        return mKeyguardFadingAwayDelay;
+    }
+
+    public long getKeyguardFadingAwayDuration() {
+        return mKeyguardFadingAwayDuration;
+    }
+
     public LinearLayout getSystemIcons() {
         return mSystemIcons;
     }
@@ -3683,11 +3763,11 @@
     }
 
     @Override
-    protected void hideRecents(boolean triggeredFromAltTab) {
+    protected void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
         // Unset the recents visibility flag
         mSystemUiVisibility &= ~View.RECENT_APPS_VISIBLE;
         notifyUiVisibilityChanged(mSystemUiVisibility);
-        super.hideRecents(triggeredFromAltTab);
+        super.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
     }
 
     @Override
@@ -3757,6 +3837,12 @@
             }
         }
 
+        public void fireNotificationLight(boolean on) {
+            for (Callback callback : mCallbacks) {
+                callback.onNotificationLight(on);
+            }
+        }
+
         public void fireNewNotifications() {
             for (Callback callback : mCallbacks) {
                 callback.onNewNotifications();
@@ -3781,10 +3867,10 @@
         }
 
         @Override
-        public void requestTease(DozeService dozeService) {
+        public void requestPulse(int pulses, DozeService dozeService) {
             if (dozeService == null) return;
             dozeService.stayAwake(PROCESSING_TIME);
-            mHandler.obtainMessage(H.REQUEST_TEASE, dozeService).sendToTarget();
+            mHandler.obtainMessage(H.REQUEST_PULSE, pulses, 0, dozeService).sendToTarget();
         }
 
         @Override
@@ -3803,9 +3889,9 @@
             mCurrentDozeService.startDozing();
         }
 
-        private void handleRequestTease(DozeService dozeService) {
+        private void handleRequestPulse(int pulses, DozeService dozeService) {
             if (!dozeService.equals(mCurrentDozeService)) return;
-            final long stayAwake = mScrimController.tease();
+            final long stayAwake = mScrimController.pulse(pulses);
             mCurrentDozeService.stayAwake(stayAwake);
         }
 
@@ -3821,15 +3907,15 @@
 
         private final class H extends Handler {
             private static final int REQUEST_DOZE = 1;
-            private static final int REQUEST_TEASE = 2;
+            private static final int REQUEST_PULSE = 2;
             private static final int DOZING_STOPPED = 3;
 
             @Override
             public void handleMessage(Message msg) {
                 if (msg.what == REQUEST_DOZE) {
                     handleRequestDoze((DozeService) msg.obj);
-                } else if (msg.what == REQUEST_TEASE) {
-                    handleRequestTease((DozeService) msg.obj);
+                } else if (msg.what == REQUEST_PULSE) {
+                    handleRequestPulse(msg.arg1, (DozeService) msg.obj);
                 } else if (msg.what == DOZING_STOPPED) {
                     handleDozingStopped((DozeService) msg.obj);
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index c2fd24c..8f25fb9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -41,6 +41,7 @@
 import com.android.systemui.statusbar.policy.NetworkController;
 import com.android.systemui.statusbar.policy.RotationLockController;
 import com.android.systemui.statusbar.policy.HotspotController;
+import com.android.systemui.statusbar.policy.SecurityController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.statusbar.policy.ZenModeController;
 
@@ -65,13 +66,15 @@
     private final FlashlightController mFlashlight;
     private final UserSwitcherController mUserSwitcherController;
     private final KeyguardMonitor mKeyguard;
+    private final SecurityController mSecurity;
 
     public QSTileHost(Context context, PhoneStatusBar statusBar,
             BluetoothController bluetooth, LocationController location,
             RotationLockController rotation, NetworkController network,
             ZenModeController zen, HotspotController hotspot,
             CastController cast, FlashlightController flashlight,
-            UserSwitcherController userSwitcher, KeyguardMonitor keyguard) {
+            UserSwitcherController userSwitcher, KeyguardMonitor keyguard,
+            SecurityController security) {
         mContext = context;
         mStatusBar = statusBar;
         mBluetooth = bluetooth;
@@ -84,6 +87,7 @@
         mFlashlight = flashlight;
         mUserSwitcherController = userSwitcher;
         mKeyguard = keyguard;
+        mSecurity = security;
 
         final HandlerThread ht = new HandlerThread(QSTileHost.class.getSimpleName());
         ht.start();
@@ -189,4 +193,8 @@
     public UserSwitcherController getUserSwitcherController() {
         return mUserSwitcherController;
     }
+
+    public SecurityController getSecurityController() {
+        return mSecurity;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index eb42401..cbd66aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -43,14 +43,13 @@
     private static final long ANIMATION_DURATION = 220;
     private static final int TAG_KEY_ANIM = R.id.scrim;
 
-    private static final int NUM_TEASES = 3;
-    private static final long TEASE_IN_ANIMATION_DURATION = 1000;
-    private static final long TEASE_VISIBLE_DURATION = 2000;
-    private static final long TEASE_OUT_ANIMATION_DURATION = 1000;
-    private static final long TEASE_INVISIBLE_DURATION = 1000;
-    private static final long TEASE_DURATION = TEASE_IN_ANIMATION_DURATION
-            + TEASE_VISIBLE_DURATION + TEASE_OUT_ANIMATION_DURATION + TEASE_INVISIBLE_DURATION;
-    private static final long PRE_TEASE_DELAY = 1000;
+    private static final long PULSE_IN_ANIMATION_DURATION = 1000;
+    private static final long PULSE_VISIBLE_DURATION = 2000;
+    private static final long PULSE_OUT_ANIMATION_DURATION = 1000;
+    private static final long PULSE_INVISIBLE_DURATION = 1000;
+    private static final long PULSE_DURATION = PULSE_IN_ANIMATION_DURATION
+            + PULSE_VISIBLE_DURATION + PULSE_OUT_ANIMATION_DURATION + PULSE_INVISIBLE_DURATION;
+    private static final long PRE_PULSE_DELAY = 1000;
 
     private final View mScrimBehind;
     private final View mScrimInFront;
@@ -70,7 +69,7 @@
     private Runnable mOnAnimationFinished;
     private boolean mAnimationStarted;
     private boolean mDozing;
-    private int mTeasesRemaining;
+    private int mPulsesRemaining;
     private final Interpolator mInterpolator = new DecelerateInterpolator();
 
     public ScrimController(View scrimBehind, View scrimInFront) {
@@ -115,27 +114,34 @@
         scheduleUpdate();
     }
 
+    public void animateGoingToFullShade(long delay, long duration) {
+        mDurationOverride = duration;
+        mAnimationDelay = delay;
+        mAnimateChange = true;
+        scheduleUpdate();
+    }
+
     public void setDozing(boolean dozing) {
         if (mDozing == dozing) return;
         mDozing = dozing;
         if (!mDozing) {
-            cancelTeasing();
+            cancelPulsing();
         }
         scheduleUpdate();
     }
 
     /** When dozing, fade screen contents in and out a few times using the front scrim. */
-    public long tease() {
+    public long pulse(int pulses) {
         if (!mDozing) return 0;
-        mTeasesRemaining = NUM_TEASES;
-        mScrimInFront.postDelayed(mTeaseIn, PRE_TEASE_DELAY);
-        return PRE_TEASE_DELAY + NUM_TEASES * TEASE_DURATION;
+        mPulsesRemaining = Math.max(pulses, mPulsesRemaining);
+        mScrimInFront.postDelayed(mPulseIn, PRE_PULSE_DELAY);
+        return PRE_PULSE_DELAY + mPulsesRemaining * PULSE_DURATION;
     }
 
-    private void cancelTeasing() {
-        mTeasesRemaining = 0;
-        mScrimInFront.removeCallbacks(mTeaseIn);
-        mScrimInFront.removeCallbacks(mTeaseOut);
+    private void cancelPulsing() {
+        mPulsesRemaining = 0;
+        mScrimInFront.removeCallbacks(mPulseIn);
+        mScrimInFront.removeCallbacks(mPulseOut);
     }
 
     private void scheduleUpdate() {
@@ -278,49 +284,49 @@
         return true;
     }
 
-    private final Runnable mTeaseIn = new Runnable() {
+    private final Runnable mPulseIn = new Runnable() {
         @Override
         public void run() {
-            if (DEBUG) Log.d(TAG, "Tease in, mDozing=" + mDozing
-                    + " mTeasesRemaining=" + mTeasesRemaining);
-            if (!mDozing || mTeasesRemaining == 0) return;
-            mTeasesRemaining--;
-            mDurationOverride = TEASE_IN_ANIMATION_DURATION;
+            if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing
+                    + " mPulsesRemaining=" + mPulsesRemaining);
+            if (!mDozing || mPulsesRemaining == 0) return;
+            mPulsesRemaining--;
+            mDurationOverride = PULSE_IN_ANIMATION_DURATION;
             mAnimationDelay = 0;
             mAnimateChange = true;
-            mOnAnimationFinished = mTeaseInFinished;
+            mOnAnimationFinished = mPulseInFinished;
             setScrimColor(mScrimInFront, 0);
         }
     };
 
-    private final Runnable mTeaseInFinished = new Runnable() {
+    private final Runnable mPulseInFinished = new Runnable() {
         @Override
         public void run() {
-            if (DEBUG) Log.d(TAG, "Tease in finished, mDozing=" + mDozing);
+            if (DEBUG) Log.d(TAG, "Pulse in finished, mDozing=" + mDozing);
             if (!mDozing) return;
-            mScrimInFront.postDelayed(mTeaseOut, TEASE_VISIBLE_DURATION);
+            mScrimInFront.postDelayed(mPulseOut, PULSE_VISIBLE_DURATION);
         }
     };
 
-    private final Runnable mTeaseOut = new Runnable() {
+    private final Runnable mPulseOut = new Runnable() {
         @Override
         public void run() {
-            if (DEBUG) Log.d(TAG, "Tease in finished, mDozing=" + mDozing);
+            if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
             if (!mDozing) return;
-            mDurationOverride = TEASE_OUT_ANIMATION_DURATION;
+            mDurationOverride = PULSE_OUT_ANIMATION_DURATION;
             mAnimationDelay = 0;
             mAnimateChange = true;
-            mOnAnimationFinished = mTeaseOutFinished;
+            mOnAnimationFinished = mPulseOutFinished;
             setScrimColor(mScrimInFront, 1);
         }
     };
 
-    private final Runnable mTeaseOutFinished = new Runnable() {
+    private final Runnable mPulseOutFinished = new Runnable() {
         @Override
         public void run() {
-            if (DEBUG) Log.d(TAG, "Tease out finished, mTeasesRemaining=" + mTeasesRemaining);
-            if (mTeasesRemaining > 0) {
-                mScrimInFront.postDelayed(mTeaseIn, TEASE_INVISIBLE_DURATION);
+            if (DEBUG) Log.d(TAG, "Pulse out finished, mPulsesRemaining=" + mPulsesRemaining);
+            if (mPulsesRemaining > 0) {
+                mScrimInFront.postDelayed(mPulseIn, PULSE_INVISIBLE_DURATION);
             }
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java
new file mode 100644
index 0000000..4a5a069
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.hardware.camera2.CameraManager;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.provider.MediaStore;
+import android.util.Log;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Handles launching the secure camera properly even when other applications may be using the camera
+ * hardware.
+ *
+ * When other applications (e.g., Face Unlock) are using the camera, they must close the camera to
+ * allow the secure camera to open it.  Since we want to minimize the delay when opening the secure
+ * camera, other apps should close the camera at the first possible opportunity (i.e., as soon as
+ * the user begins swiping to go to the secure camera).
+ *
+ * If the camera is unavailable when the user begins to swipe, the SecureCameraLaunchManager sends a
+ * broadcast to tell other apps to close the camera.  When and if the user completes their swipe to
+ * launch the secure camera, the SecureCameraLaunchManager delays launching the secure camera until
+ * a callback indicates that the camera has become available.  If it doesn't receive that callback
+ * within a specified timeout period, the secure camera is launched anyway.
+ *
+ * Ideally, the secure camera would handle waiting for the camera to become available.  This allows
+ * some of the time necessary to close the camera to happen in parallel with starting the secure
+ * camera app.  We can't rely on all third-party camera apps to handle this.  However, an app can
+ * put com.android.systemui.statusbar.phone.will_wait_for_camera_available in its meta-data to
+ * indicate that it will be responsible for waiting for the camera to become available.
+ *
+ * It is assumed that the functions in this class, including the constructor, will be called from
+ * the UI thread.
+ */
+public class SecureCameraLaunchManager {
+    // TODO(bcolonna): Turn off debugging after running with this change for a while. STOPSHIP
+    private static final boolean DEBUG = true;
+    private static final String TAG = "SecureCameraLaunchManager";
+
+    // Action sent as a broadcast to tell other apps to stop using the camera.  Other apps that use
+    // the camera from keyguard (e.g., Face Unlock) should listen for this broadcast and close the
+    // camera as soon as possible after receiving it.
+    private static final String CLOSE_CAMERA_ACTION_NAME =
+            "com.android.systemui.statusbar.phone.CLOSE_CAMERA";
+
+    // Apps should put this field in their meta-data to indicate that they will take on the
+    // responsibility of waiting for the camera to become available.  If this field is present, the
+    // SecureCameraLaunchManager launches the secure camera even if the camera hardware has not
+    // become available.  Having the secure camera app do the waiting is the optimal approach, but
+    // without this field, the SecureCameraLaunchManager doesn't launch the secure camera until the
+    // camera hardware is available.
+    private static final String META_DATA_WILL_WAIT_FOR_CAMERA_AVAILABLE =
+            "com.android.systemui.statusbar.phone.will_wait_for_camera_available";
+
+    // If the camera hardware hasn't become available after this period of time, the
+    // SecureCameraLaunchManager launches the secure camera anyway.
+    private static final int CAMERA_AVAILABILITY_TIMEOUT_MS = 1000;
+
+    private Context mContext;
+    private Handler mHandler;
+    private LockPatternUtils mLockPatternUtils;
+    private KeyguardBottomAreaView mKeyguardBottomArea;
+
+    private CameraManager mCameraManager;
+    private CameraAvailabilityListener mCameraAvailabilityListener;
+    private Map<String, Boolean> mCameraAvailabilityMap;
+    private boolean mWaitingToLaunchSecureCamera;
+    private Runnable mLaunchCameraRunnable;
+
+    private class CameraAvailabilityListener extends CameraManager.AvailabilityListener {
+        @Override
+        public void onCameraUnavailable(String cameraId) {
+            if (DEBUG) Log.d(TAG, "onCameraUnavailble(" + cameraId + ")");
+            mCameraAvailabilityMap.put(cameraId, false);
+        }
+
+        @Override
+        public void onCameraAvailable(String cameraId) {
+            if (DEBUG) Log.d(TAG, "onCameraAvailable(" + cameraId + ")");
+            mCameraAvailabilityMap.put(cameraId, true);
+
+            // If we were waiting for the camera hardware to become available to launch the
+            // secure camera, we can launch it now if all cameras are available.  If one or more
+            // cameras are still not available, we will get this callback again for those
+            // cameras.
+            if (mWaitingToLaunchSecureCamera && areAllCamerasAvailable()) {
+                mKeyguardBottomArea.launchCamera();
+                mWaitingToLaunchSecureCamera = false;
+
+                // We no longer need to launch the camera after the timeout hits.
+                mHandler.removeCallbacks(mLaunchCameraRunnable);
+            }
+        }
+    }
+
+    public SecureCameraLaunchManager(Context context, KeyguardBottomAreaView keyguardBottomArea) {
+        mContext = context;
+        mHandler = new Handler();
+        mLockPatternUtils = new LockPatternUtils(context);
+        mKeyguardBottomArea = keyguardBottomArea;
+
+        mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
+        mCameraAvailabilityListener = new CameraAvailabilityListener();
+
+        // An onCameraAvailable() or onCameraUnavailable() callback will be received for each camera
+        // when the availability listener is registered, thus initializing the map.
+        //
+        // Keeping track of the state of all cameras using the onCameraAvailable() and
+        // onCameraUnavailable() callbacks can get messy when dealing with hot-pluggable cameras.
+        // However, we have a timeout in place such that we will never hang waiting for cameras.
+        mCameraAvailabilityMap = new HashMap<String, Boolean>();
+
+        mWaitingToLaunchSecureCamera = false;
+        mLaunchCameraRunnable = new Runnable() {
+                @Override
+                public void run() {
+                    if (mWaitingToLaunchSecureCamera) {
+                        Log.w(TAG, "Timeout waiting for camera availability");
+                        mKeyguardBottomArea.launchCamera();
+                        mWaitingToLaunchSecureCamera = false;
+                    }
+                }
+            };
+    }
+
+    /**
+     * Initializes the SecureCameraManager and starts listening for camera availability.
+     */
+    public void create() {
+        mCameraManager.addAvailabilityListener(mCameraAvailabilityListener, mHandler);
+    }
+
+    /**
+     * Stops listening for camera availability and cleans up the SecureCameraManager.
+     */
+    public void destroy() {
+        mCameraManager.removeAvailabilityListener(mCameraAvailabilityListener);
+    }
+
+    /**
+     * Called when the user is starting to swipe horizontally, possibly to start the secure camera.
+     * Although this swipe ultimately may not result in the secure camera opening, we need to stop
+     * all other camera usage (e.g., Face Unlock) as soon as possible.  We send out a broadcast to
+     * notify other apps that they should close the camera immediately.  The broadcast is sent even
+     * if the camera appears to be available, because there could be an app that is about to open
+     * the camera.
+     */
+    public void onSwipingStarted() {
+        if (DEBUG) Log.d(TAG, "onSwipingStarted");
+        AsyncTask.execute(new Runnable() {
+                @Override
+                public void run() {
+                    Intent intent = new Intent();
+                    intent.setAction(CLOSE_CAMERA_ACTION_NAME);
+                    mContext.sendBroadcast(intent);
+                }
+            });
+    }
+
+    /**
+     * Called when the secure camera should be started.  If the camera is available or the secure
+     * camera app has indicated that it will wait for camera availability, the secure camera app is
+     * launched immediately.  Otherwise, we wait for the camera to become available (or timeout)
+     * before launching the secure camera.
+     */
+    public void startSecureCameraLaunch() {
+        if (DEBUG) Log.d(TAG, "startSecureCameraLunch");
+        if (areAllCamerasAvailable() || targetWillWaitForCameraAvailable()) {
+            mKeyguardBottomArea.launchCamera();
+        } else {
+            mWaitingToLaunchSecureCamera = true;
+            mHandler.postDelayed(mLaunchCameraRunnable, CAMERA_AVAILABILITY_TIMEOUT_MS);
+        }
+    }
+
+    /**
+     * Returns true if all of the cameras we are tracking are currently available.
+     */
+    private boolean areAllCamerasAvailable() {
+        for (boolean cameraAvailable: mCameraAvailabilityMap.values()) {
+            if (!cameraAvailable) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Determines if the secure camera app will wait for the camera hardware to become available
+     * before trying to open the camera.  If so, we can fire off an intent to start the secure
+     * camera app before the camera is available.  Otherwise, it is our responsibility to wait for
+     * the camera hardware to become available before firing off the intent to start the secure
+     * camera.
+     *
+     * Ideally we are able to fire off the secure camera intent as early as possibly so that, if the
+     * camera is closing, it can continue to close while the secure camera app is opening.  This
+     * improves secure camera startup time.
+     */
+    private boolean targetWillWaitForCameraAvailable() {
+        // Create intent that would launch the secure camera.
+        Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
+                .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+        PackageManager packageManager = mContext.getPackageManager();
+
+        // Get the list of applications that can handle the intent.
+        final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
+                intent, PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser());
+        if (appList.size() == 0) {
+            if (DEBUG) Log.d(TAG, "No targets found for secure camera intent");
+            return false;
+        }
+
+        // Get the application that the intent resolves to.
+        ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
+                PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
+                mLockPatternUtils.getCurrentUser());
+
+        if (resolved == null || resolved.activityInfo == null) {
+            return false;
+        }
+
+        // If we would need to launch the resolver activity, then we can't assume that the target
+        // is one that would wait for the camera.
+        if (wouldLaunchResolverActivity(resolved, appList)) {
+            if (DEBUG) Log.d(TAG, "Secure camera intent would launch resolver");
+            return false;
+        }
+
+        // If the target doesn't have meta-data we must assume it won't wait for the camera.
+        if (resolved.activityInfo.metaData == null || resolved.activityInfo.metaData.isEmpty()) {
+            if (DEBUG) Log.d(TAG, "No meta-data found for secure camera application");
+            return false;
+        }
+
+        // Check the secure camera app meta-data to see if it indicates that it will wait for the
+        // camera to become available.
+        boolean willWaitForCameraAvailability =
+                resolved.activityInfo.metaData.getBoolean(META_DATA_WILL_WAIT_FOR_CAMERA_AVAILABLE);
+
+        if (DEBUG) Log.d(TAG, "Target will wait for camera: " + willWaitForCameraAvailability);
+
+        return willWaitForCameraAvailability;
+    }
+
+    /**
+     * Determines if the activity that would be launched by the intent is the ResolverActivity.
+     */
+    private boolean wouldLaunchResolverActivity(ResolveInfo resolved, List<ResolveInfo> appList) {
+        // If the list contains the resolved activity, then it can't be the ResolverActivity itself.
+        for (int i = 0; i < appList.size(); i++) {
+            ResolveInfo tmp = appList.get(i);
+            if (tmp.activityInfo.name.equals(resolved.activityInfo.name)
+                    && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index b3051b4..0c62fd3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -243,21 +243,25 @@
         boolean changed = expanded != mExpanded;
         mExpanded = expanded;
         if (changed) {
-            updateHeights();
-            updateVisibilities();
-            updateSystemIconsLayoutParams();
-            updateClickTargets();
-            updateMultiUserSwitch();
-            if (mQSPanel != null) {
-                mQSPanel.setExpanded(expanded);
-            }
-            updateClockScale();
-            updateAvatarScale();
-            updateClockLp();
-            requestCaptureValues();
+            updateEverything();
         }
     }
 
+    public void updateEverything() {
+        updateHeights();
+        updateVisibilities();
+        updateSystemIconsLayoutParams();
+        updateClickTargets();
+        updateMultiUserSwitch();
+        if (mQSPanel != null) {
+            mQSPanel.setExpanded(mExpanded);
+        }
+        updateClockScale();
+        updateAvatarScale();
+        updateClockLp();
+        requestCaptureValues();
+    }
+
     private void updateHeights() {
         int height = mExpanded ? mExpandedHeight : mCollapsedHeight;
         ViewGroup.LayoutParams lp = getLayoutParams();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index af21f25..6831933 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -230,17 +230,22 @@
             });
         } else {
             mPhoneStatusBar.setKeyguardFadingAway(delay, fadeoutDuration);
-            mPhoneStatusBar.hideKeyguard();
-            mStatusBarWindowManager.setKeyguardFadingAway(true);
+            boolean staying = mPhoneStatusBar.hideKeyguard();
+            if (!staying) {
+                mStatusBarWindowManager.setKeyguardFadingAway(true);
+                mScrimController.animateKeyguardFadingOut(delay, fadeoutDuration, new Runnable() {
+                    @Override
+                    public void run() {
+                        mStatusBarWindowManager.setKeyguardFadingAway(false);
+                        mPhoneStatusBar.finishKeyguardFadingAway();
+                    }
+                });
+            } else {
+                mScrimController.animateGoingToFullShade(delay, fadeoutDuration);
+                mPhoneStatusBar.finishKeyguardFadingAway();
+            }
             mStatusBarWindowManager.setKeyguardShowing(false);
             mBouncer.animateHide(delay, fadeoutDuration);
-            mScrimController.animateKeyguardFadingOut(delay, fadeoutDuration, new Runnable() {
-                @Override
-                public void run() {
-                    mStatusBarWindowManager.setKeyguardFadingAway(false);
-                    mPhoneStatusBar.finishKeyguardFadingAway();
-                }
-            });
             mViewMediatorCallback.keyguardGone();
             updateStates();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index 86a6622..d701b3c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -27,8 +27,12 @@
  */
 public class SystemUIDialog extends AlertDialog {
 
+    private final Context mContext;
+
     public SystemUIDialog(Context context) {
         super(context, R.style.Theme_SystemUI_Dialog);
+        mContext = context;
+
         getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
                 | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
@@ -36,4 +40,26 @@
         attrs.setTitle(getClass().getSimpleName());
         getWindow().setAttributes(attrs);
     }
+
+    public void setShowForAllUsers(boolean show) {
+        if (show) {
+            getWindow().getAttributes().privateFlags |=
+                    WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+        } else {
+            getWindow().getAttributes().privateFlags &=
+                    ~WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+        }
+    }
+
+    public void setMessage(int resId) {
+        setMessage(mContext.getString(resId));
+    }
+
+    public void setPositiveButton(int resId, OnClickListener onClick) {
+        setButton(BUTTON_POSITIVE, mContext.getString(resId), onClick);
+    }
+
+    public void setNegativeButton(int resId, OnClickListener onClick) {
+        setButton(BUTTON_NEGATIVE, mContext.getString(resId), onClick);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index 1e65543..d1b69ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -47,6 +47,7 @@
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_BATTERY_CHANGED);
         filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
+        filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING);
         context.registerReceiver(this, filter);
 
         updatePowerSave();
@@ -86,6 +87,8 @@
             fireBatteryLevelChanged();
         } else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)) {
             updatePowerSave();
+        } else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING)) {
+            setPowerSave(intent.getBooleanExtra(PowerManager.EXTRA_POWER_SAVE_MODE, false));
         }
     }
 
@@ -94,7 +97,10 @@
     }
 
     private void updatePowerSave() {
-        final boolean powerSave = mPowerManager.isPowerSaveMode();
+        setPowerSave(mPowerManager.isPowerSaveMode());
+    }
+
+    private void setPowerSave(boolean powerSave) {
         if (powerSave == mPowerSave) return;
         mPowerSave = powerSave;
         if (DEBUG) Log.d(TAG, "Power save is " + (mPowerSave ? "on" : "off"));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
index 36cfb86..70eaa5c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
@@ -44,9 +44,6 @@
     private static final String TAG = "FlashlightController";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
-    private static final boolean ENFORCE_AVAILABILITY_LISTENER =
-            SystemProperties.getBoolean("persist.sysui.flash.listener", false);
-
     private static final int DISPATCH_ERROR = 0;
     private static final int DISPATCH_OFF = 1;
     private static final int DISPATCH_AVAILABILITY_CHANGED = 2;
@@ -82,9 +79,10 @@
             return;
         }
 
-        ensureHandler();
-        mCameraAvailable = true;
-        mCameraManager.addAvailabilityListener(mAvailabilityListener, mHandler);
+        if (mCameraId != null) {
+            ensureHandler();
+            mCameraManager.addAvailabilityListener(mAvailabilityListener, mHandler);
+        }
     }
 
     public synchronized void setFlashlight(boolean enabled) {
@@ -105,7 +103,7 @@
     }
 
     public synchronized boolean isAvailable() {
-        return ENFORCE_AVAILABILITY_LISTENER ? mCameraAvailable : (mCameraId != null);
+        return mCameraAvailable;
     }
 
     public void addListener(FlashlightListener l) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
index c2fa68f..6ae076f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -70,6 +70,15 @@
         if (DEBUG) Log.v(TAG, "create() " + mTouchSensitivityDelay);
     }
 
+    public void updateResources() {
+        if (mContentHolder != null) {
+            final LayoutParams lp = (LayoutParams) mContentHolder.getLayoutParams();
+            lp.width = getResources().getDimensionPixelSize(R.dimen.notification_panel_width);
+            lp.gravity = getResources().getInteger(R.integer.notification_panel_layout_gravity);
+            mContentHolder.setLayoutParams(lp);
+        }
+    }
+
     public void setBar(PhoneStatusBar bar) {
         mBar = bar;
     }
@@ -91,7 +100,9 @@
 
         if (mHeadsUp != null) {
             mHeadsUp.row.setSystemExpanded(true);
-            mHeadsUp.row.setShowingPublic(false);
+            mHeadsUp.row.setSensitive(false);
+            mHeadsUp.row.setHideSensitive(
+                    false, false /* animated */, 0 /* delay */, 0 /* duration */);
             if (mContentHolder == null) {
                 // too soon!
                 return false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index eea8396..dd706bb9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -16,18 +16,20 @@
 
 package com.android.systemui.statusbar.policy;
 
-import java.util.ArrayList;
-
 import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.ConnectivityManager;
 import android.net.wifi.WifiManager;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.util.Log;
 
+import java.util.ArrayList;
+
 public class HotspotControllerImpl implements HotspotController {
 
     private static final String TAG = "HotspotController";
@@ -73,7 +75,26 @@
 
     @Override
     public void setHotspotEnabled(boolean enabled) {
+        final ContentResolver cr = mContext.getContentResolver();
+        // This needs to be kept up to date with Settings (WifiApEnabler.setSoftapEnabled)
+        // in case it is turned on in settings and off in qs (or vice versa).
+        // Disable Wifi if enabling tethering.
+        int wifiState = mWifiManager.getWifiState();
+        if (enabled && ((wifiState == WifiManager.WIFI_STATE_ENABLING) ||
+                    (wifiState == WifiManager.WIFI_STATE_ENABLED))) {
+            mWifiManager.setWifiEnabled(false);
+            Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 1);
+        }
+
         mWifiManager.setWifiApEnabled(null, enabled);
+
+        // If needed, restore Wifi on tether disable.
+        if (!enabled) {
+            if (Settings.Global.getInt(cr, Settings.Global.WIFI_SAVED_STATE, 0) == 1) {
+                mWifiManager.setWifiEnabled(true);
+                Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 0);
+            }
+        }
     }
 
     private void fireCallback(boolean isEnabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 0134fe8..330b599 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -63,7 +63,6 @@
                     // Just an old-fashioned ImageView
                     performLongClick();
                 }
-                setPressed(false);
             }
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
index 6795842..a0312bc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
@@ -36,8 +36,6 @@
 
     private static final String TAG = "KeyguardUserSwitcher";
     private static final boolean ALWAYS_ON = false;
-    private static final String SIMPLE_USER_SWITCHER_GLOBAL_SETTING =
-            "lockscreenSimpleUserSwitcher";
 
     private final ViewGroup mUserSwitcher;
     private final KeyguardStatusBarView mStatusBarView;
@@ -52,8 +50,7 @@
             mStatusBarView.setKeyguardUserSwitcher(this);
             mAdapter = new Adapter(context, userSwitcherController);
             mAdapter.registerDataSetObserver(mDataSetObserver);
-            mSimpleUserSwitcher = Settings.Global.getInt(context.getContentResolver(),
-                    SIMPLE_USER_SWITCHER_GLOBAL_SETTING, 0) != 0;
+            mSimpleUserSwitcher = userSwitcherController.isSimpleUserSwitcher();
         } else {
             mUserSwitcher = null;
             mStatusBarView = null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 70fe85f..4e9f37d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -34,7 +34,6 @@
 import android.os.Messenger;
 import android.provider.Settings;
 import android.telephony.PhoneStateListener;
-import android.telephony.Rlog;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
@@ -471,8 +470,8 @@
     PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
         @Override
         public void onSignalStrengthsChanged(SignalStrength signalStrength) {
-            if (true/*DEBUG*/) {
-                Rlog.d(TAG, "onSignalStrengthsChanged signalStrength=" + signalStrength +
+            if (DEBUG) {
+                Log.d(TAG, "onSignalStrengthsChanged signalStrength=" + signalStrength +
                     ((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel())));
             }
             mSignalStrength = signalStrength;
@@ -482,8 +481,8 @@
 
         @Override
         public void onServiceStateChanged(ServiceState state) {
-            if (true/*DEBUG*/) {
-                Rlog.d(TAG, "onServiceStateChanged voiceState=" + state.getVoiceRegState()
+            if (DEBUG) {
+                Log.d(TAG, "onServiceStateChanged voiceState=" + state.getVoiceRegState()
                         + " dataState=" + state.getDataRegState());
             }
             mServiceState = state;
@@ -495,8 +494,8 @@
 
         @Override
         public void onCallStateChanged(int state, String incomingNumber) {
-            if (true/*DEBUG*/) {
-                Rlog.d(TAG, "onCallStateChanged state=" + state);
+            if (DEBUG) {
+                Log.d(TAG, "onCallStateChanged state=" + state);
             }
             // In cdma, if a voice call is made, RSSI should switch to 1x.
             if (isCdma()) {
@@ -507,8 +506,8 @@
 
         @Override
         public void onDataConnectionStateChanged(int state, int networkType) {
-            if (true/*DEBUG*/) {
-                Rlog.d(TAG, "onDataConnectionStateChanged: state=" + state
+            if (DEBUG) {
+                Log.d(TAG, "onDataConnectionStateChanged: state=" + state
                         + " type=" + networkType);
             }
             mDataState = state;
@@ -520,8 +519,8 @@
 
         @Override
         public void onDataActivity(int direction) {
-            if (true/*DEBUG*/) {
-                Rlog.d(TAG, "onDataActivity: direction=" + direction);
+            if (DEBUG) {
+                Log.d(TAG, "onDataActivity: direction=" + direction);
             }
             mDataActivity = direction;
             updateDataIcon();
@@ -552,7 +551,7 @@
         } else {
             mSimState = IccCardConstants.State.UNKNOWN;
         }
-        Rlog.d(TAG, "updateSimState: mSimState=" + mSimState);
+        if (DEBUG) Log.d(TAG, "updateSimState: mSimState=" + mSimState);
     }
 
     private boolean isCdma() {
@@ -580,7 +579,7 @@
         } else {
             retVal = false;
         }
-        Rlog.d(TAG, "hasService: mServiceState=" + mServiceState + " retVal=" + retVal);
+        if (DEBUG) Log.d(TAG, "hasService: mServiceState=" + mServiceState + " retVal=" + retVal);
         return retVal;
     }
 
@@ -594,21 +593,18 @@
     }
 
     private final void updateTelephonySignalStrength() {
-        Rlog.d(TAG, "updateTelephonySignalStrength: hasService=" + hasService() + " ss=" + mSignalStrength);
-        if (mDemoMode) {
-            mQSPhoneSignalIconId = mDemoMobileLevel < 0 ? R.drawable.ic_qs_signal_no_signal :
-                    TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[mDemoInetCondition][mDemoMobileLevel];
-            mQSDataTypeIconId = mDemoQSDataTypeIconId;
-            return;
+        if (DEBUG) {
+            Log.d(TAG, "updateTelephonySignalStrength: hasService=" + hasService()
+                    + " ss=" + mSignalStrength);
         }
         if (!hasService()) {
-            if (true/*CHATTY*/) Log.d(TAG, "updateTelephonySignalStrength: !hasService()");
+            if (CHATTY) Log.d(TAG, "updateTelephonySignalStrength: !hasService()");
             mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
             mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal;
             mDataSignalIconId = R.drawable.stat_sys_signal_null;
         } else {
             if (mSignalStrength == null) {
-                if (true/*CHATTY*/) Rlog.d(TAG, "updateTelephonySignalStrength: mSignalStrength == null");
+                if (CHATTY) Log.d(TAG, "updateTelephonySignalStrength: mSignalStrength == null");
                 mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
                 mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal;
                 mDataSignalIconId = R.drawable.stat_sys_signal_null;
@@ -619,9 +615,12 @@
                 int[] iconList;
                 if (isCdma() && mAlwaysShowCdmaRssi) {
                     mLastSignalLevel = iconLevel = mSignalStrength.getCdmaLevel();
-                    if(true/*DEBUG*/) Rlog.d(TAG, "updateTelephonySignalStrength: mAlwaysShowCdmaRssi=" + mAlwaysShowCdmaRssi
+                    if (DEBUG) {
+                        Log.d(TAG, "updateTelephonySignalStrength:"
+                            + " mAlwaysShowCdmaRssi=" + mAlwaysShowCdmaRssi
                             + " set to cdmaLevel=" + mSignalStrength.getCdmaLevel()
                             + " instead of level=" + mSignalStrength.getLevel());
+                    }
                 } else {
                     mLastSignalLevel = iconLevel = mSignalStrength.getLevel();
                 }
@@ -646,7 +645,7 @@
                 mContentDescriptionPhoneSignal = mContext.getString(
                         AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[iconLevel]);
                 mDataSignalIconId = TelephonyIcons.DATA_SIGNAL_STRENGTH[mInetCondition][iconLevel];
-                Rlog.d(TAG, "updateTelephonySignalStrength: iconLevel=" + iconLevel);
+                if (DEBUG) Log.d(TAG, "updateTelephonySignalStrength: iconLevel=" + iconLevel);
             }
         }
     }
@@ -950,11 +949,6 @@
     }
 
     private void updateWifiIcons() {
-        if (mDemoMode) {
-            mQSWifiIconId = mDemoWifiLevel < 0 ? R.drawable.ic_qs_wifi_no_network
-                    : WifiIcons.QS_WIFI_SIGNAL_STRENGTH[mDemoInetCondition][mDemoWifiLevel];
-            return;
-        }
         if (mWifiConnected) {
             mWifiIconId = WifiIcons.WIFI_SIGNAL_STRENGTH[mInetCondition][mWifiLevel];
             mQSWifiIconId = WifiIcons.QS_WIFI_SIGNAL_STRENGTH[mInetCondition][mWifiLevel];
@@ -1209,6 +1203,14 @@
             }
         }
 
+        if (mDemoMode) {
+            mQSWifiIconId = mDemoWifiLevel < 0 ? R.drawable.ic_qs_wifi_no_network
+                    : WifiIcons.QS_WIFI_SIGNAL_STRENGTH[mDemoInetCondition][mDemoWifiLevel];
+            mQSPhoneSignalIconId = mDemoMobileLevel < 0 ? R.drawable.ic_qs_signal_no_signal :
+                    TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[mDemoInetCondition][mDemoMobileLevel];
+            mQSDataTypeIconId = mDemoQSDataTypeIconId;
+        }
+
         if (DEBUG) {
             Log.d(TAG, "refreshViews connected={"
                     + (mWifiConnected?" wifi":"")
@@ -1497,8 +1499,6 @@
             for (SignalCluster cluster : mSignalClusters) {
                 refreshSignalCluster(cluster);
             }
-            updateWifiIcons();
-            updateTelephonySignalStrength();
             refreshViews();
         } else if (mDemoMode && command.equals(COMMAND_NETWORK)) {
             String airplane = args.getString("airplane");
@@ -1528,7 +1528,6 @@
                             iconId,
                             "Demo");
                 }
-                updateWifiIcons();
                 refreshViews();
             }
             String mobile = args.getString("mobile");
@@ -1574,7 +1573,6 @@
                             "Demo",
                             "Demo");
                 }
-                updateTelephonySignalStrength();
                 refreshViews();
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
index d405172..cdbe494 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
@@ -107,6 +107,19 @@
         return info;
     }
 
+    public boolean wouldLaunchResolverActivity(Intent intent) {
+        PackageManager packageManager = mContext.getPackageManager();
+        final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
+                intent, PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser());
+        if (appList.size() == 0) {
+            return false;
+        }
+        ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
+                PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
+                mLockPatternUtils.getCurrentUser());
+        return wouldLaunchResolverActivity(resolved, appList);
+    }
+
     private boolean wouldLaunchResolverActivity(ResolveInfo resolved, List<ResolveInfo> appList) {
         // If the list contains the above resolved activity, then it can't be
         // ResolverActivity itself.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java
new file mode 100644
index 0000000..ede8129
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.policy;
+
+public interface SecurityController {
+
+    boolean hasDeviceOwner();
+    String getDeviceOwnerName();
+    boolean isVpnEnabled();
+    String getVpnApp();
+    boolean isLegacyVpn();
+    String getLegacyVpnName();
+    void openVpnApp();
+    void disconnectFromLegacyVpn();
+
+    void addCallback(VpnCallback callback);
+    void removeCallback(VpnCallback callback);
+
+    public interface VpnCallback {
+        void onVpnStateChanged();
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
new file mode 100644
index 0000000..8e04e5e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.policy;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.IConnectivityManager;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.net.VpnConfig;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+public class SecurityControllerImpl implements SecurityController {
+
+    private static final String TAG = "SecurityController";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private static final NetworkRequest REQUEST = new NetworkRequest.Builder()
+            .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
+            .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+            .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+            .build();
+    private final Context mContext;
+    private final ConnectivityManager mConnectivityManager;
+    private final IConnectivityManager mConnectivityService = IConnectivityManager.Stub.asInterface(
+                ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
+    private final DevicePolicyManager mDevicePolicyManager;
+    private final ArrayList<VpnCallback> mCallbacks = new ArrayList<VpnCallback>();
+
+    private boolean mIsVpnEnabled;
+    private VpnConfig mVpnConfig;
+    private String mVpnName;
+
+    public SecurityControllerImpl(Context context) {
+        mContext = context;
+        mDevicePolicyManager = (DevicePolicyManager)
+                context.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        mConnectivityManager = (ConnectivityManager)
+                context.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+        // TODO: re-register network callback on user change.
+        mConnectivityManager.registerNetworkCallback(REQUEST, mNetworkCallback);
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("SecurityController state:");
+        pw.print("  mIsVpnEnabled="); pw.println(mIsVpnEnabled);
+        pw.print("  mVpnConfig="); pw.println(mVpnConfig);
+        pw.print("  mVpnName="); pw.println(mVpnName);
+    }
+
+    @Override
+    public boolean hasDeviceOwner() {
+        return !TextUtils.isEmpty(mDevicePolicyManager.getDeviceOwner());
+    }
+
+    @Override
+    public String getDeviceOwnerName() {
+        return mDevicePolicyManager.getDeviceOwnerName();
+    }
+
+    @Override
+    public boolean isVpnEnabled() {
+        // TODO: Remove once using NetworkCallback for updates.
+        updateState();
+
+        return mIsVpnEnabled;
+    }
+
+    @Override
+    public boolean isLegacyVpn() {
+        return mVpnConfig.legacy;
+    }
+
+    @Override
+    public String getVpnApp() {
+        return mVpnName;
+    }
+
+    @Override
+    public String getLegacyVpnName() {
+        return mVpnConfig.session;
+    }
+
+    @Override
+    public void openVpnApp() {
+        Intent i = mContext.getPackageManager().getLaunchIntentForPackage(mVpnConfig.user);
+        if (i != null) {
+            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            mContext.startActivity(i);
+        }
+    }
+
+    @Override
+    public void disconnectFromLegacyVpn() {
+        try {
+            mConnectivityService.prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN);
+        } catch (Exception e) {
+            Log.e(TAG, "Unable to disconnect from VPN", e);
+        }
+    }
+
+    @Override
+    public void addCallback(VpnCallback callback) {
+        if (callback == null) return;
+        if (DEBUG) Log.d(TAG, "removeCallback " + callback);
+        mCallbacks.remove(callback);
+    }
+
+    @Override
+    public void removeCallback(VpnCallback callback) {
+        if (callback == null || mCallbacks.contains(callback)) return;
+        if (DEBUG) Log.d(TAG, "addCallback " + callback);
+        mCallbacks.add(callback);
+    }
+
+    private void fireCallbacks() {
+        for (VpnCallback callback : mCallbacks) {
+            callback.onVpnStateChanged();
+        }
+    }
+
+    private void updateState() {
+        try {
+            mVpnConfig = mConnectivityService.getVpnConfig();
+
+            // TODO: Remove once using NetworkCallback for updates.
+            mIsVpnEnabled = mVpnConfig != null;
+
+            if (mVpnConfig != null && !mVpnConfig.legacy) {
+                ApplicationInfo info =
+                        mContext.getPackageManager().getApplicationInfo(mVpnConfig.user, 0);
+                mVpnName = mContext.getPackageManager().getApplicationLabel(info).toString();
+            }
+        } catch (RemoteException | NameNotFoundException e) {
+            Log.w(TAG, "Unable to get current VPN", e);
+        }
+    }
+
+    private final NetworkCallback mNetworkCallback = new NetworkCallback() {
+        public void onCapabilitiesChanged(android.net.Network network,
+                android.net.NetworkCapabilities networkCapabilities) {
+            if (DEBUG) Log.d(TAG, "onCapabilitiesChanged " + networkCapabilities);
+            mIsVpnEnabled = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
+            updateState();
+            fireCallbacks();
+        }
+    };
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 7c00c7f..6e3656d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -32,11 +32,14 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.UserInfo;
+import android.database.ContentObserver;
 import android.graphics.Bitmap;
 import android.os.AsyncTask;
+import android.os.Handler;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.Settings;
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.View;
@@ -57,12 +60,15 @@
 
     private static final String TAG = "UserSwitcherController";
     private static final boolean DEBUG = false;
+    private static final String SIMPLE_USER_SWITCHER_GLOBAL_SETTING =
+            "lockscreenSimpleUserSwitcher";
 
     private final Context mContext;
     private final UserManager mUserManager;
     private final ArrayList<WeakReference<BaseUserAdapter>> mAdapters = new ArrayList<>();
     private final GuestResumeSessionReceiver mGuestResumeSessionReceiver
             = new GuestResumeSessionReceiver();
+    private boolean mSimpleUserSwitcher;
 
     private ArrayList<UserRecord> mUsers = new ArrayList<>();
     private Dialog mExitGuestDialog;
@@ -80,6 +86,13 @@
         filter.addAction(Intent.ACTION_USER_STOPPING);
         mContext.registerReceiverAsUser(mReceiver, UserHandle.OWNER, filter,
                 null /* permission */, null /* scheduler */);
+
+        mSimpleUserSwitcher = Settings.Global.getInt(context.getContentResolver(),
+                SIMPLE_USER_SWITCHER_GLOBAL_SETTING, 0) != 0;
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Global.getUriFor(SIMPLE_USER_SWITCHER_GLOBAL_SETTING), true,
+                mSimpleUserSwitcherObserver);
+
         refreshUsers(UserHandle.USER_NULL);
     }
 
@@ -136,11 +149,13 @@
                     }
                 }
 
-                if (guestRecord == null) {
-                    records.add(new UserRecord(null /* info */, null /* picture */,
-                            true /* isGuest */, false /* isCurrent */));
-                } else {
-                    records.add(guestRecord);
+                if (!mSimpleUserSwitcher) {
+                    if (guestRecord == null) {
+                        records.add(new UserRecord(null /* info */, null /* picture */,
+                                true /* isGuest */, false /* isCurrent */));
+                    } else {
+                        records.add(guestRecord);
+                    }
                 }
 
                 return records;
@@ -167,6 +182,10 @@
         }
     }
 
+    public boolean isSimpleUserSwitcher() {
+        return mSimpleUserSwitcher;
+    }
+
     public void switchTo(UserRecord record) {
         int id;
         if (record.isGuest && record.info == null) {
@@ -253,6 +272,14 @@
         }
     };
 
+    private final ContentObserver mSimpleUserSwitcherObserver = new ContentObserver(new Handler()) {
+        public void onChange(boolean selfChange) {
+            mSimpleUserSwitcher = Settings.Global.getInt(mContext.getContentResolver(),
+                    SIMPLE_USER_SWITCHER_GLOBAL_SETTING, 0) != 0;
+            refreshUsers(UserHandle.USER_NULL);
+        };
+    };
+
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("UserSwitcherController state:");
         pw.println("  mLastNonGuestUser=" + mLastNonGuestUser);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
index 0582140..ddb5cb8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
@@ -34,6 +34,7 @@
     private int mSpeedBumpIndex = -1;
     private float mScrimAmount;
     private boolean mDark;
+    private boolean mHideSensitive;
 
     public int getScrollY() {
         return mScrollY;
@@ -68,6 +69,10 @@
         mDark = dark;
     }
 
+    public void setHideSensitive(boolean hideSensitive) {
+        mHideSensitive = hideSensitive;
+    }
+
     /**
      * In dimmed mode, a child can be activated, which happens on the first tap of the double-tap
      * interaction. This child is then scaled normally and its background is fully opaque.
@@ -84,6 +89,10 @@
         return mDark;
     }
 
+    public boolean isHideSensitive() {
+        return mHideSensitive;
+    }
+
     public ActivatableNotificationView getActivatedChild() {
         return mActivatedChild;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
index 99d3a01..3c93b19 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
@@ -30,7 +30,9 @@
     boolean animateTopInset;
     boolean animateDimmed;
     boolean animateDark;
+    boolean animateHideSensitive;
     boolean hasDelays;
+    boolean hasGoToFullShadeEvent;
 
     public AnimationFilter animateAlpha() {
         animateAlpha = true;
@@ -77,6 +79,11 @@
         return this;
     }
 
+    public AnimationFilter animateHideSensitive() {
+        animateHideSensitive = true;
+        return this;
+    }
+
     /**
      * Combines multiple filters into {@code this} filter, using or as the operand .
      *
@@ -87,6 +94,10 @@
         int size = events.size();
         for (int i = 0; i < size; i++) {
             combineFilter(events.get(i).filter);
+            if (events.get(i).animationType ==
+                    NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_GO_TO_FULL_SHADE) {
+                hasGoToFullShadeEvent = true;
+            }
         }
     }
 
@@ -99,6 +110,7 @@
         animateTopInset |= filter.animateTopInset;
         animateDimmed |= filter.animateDimmed;
         animateDark |= filter.animateDark;
+        animateHideSensitive |= filter.animateHideSensitive;
         hasDelays |= filter.hasDelays;
     }
 
@@ -111,6 +123,8 @@
         animateTopInset = false;
         animateDimmed = false;
         animateDark = false;
+        animateHideSensitive = false;
         hasDelays = false;
+        hasGoToFullShadeEvent = false;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index e0167e9..fec5e74 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -36,6 +36,7 @@
 import com.android.systemui.SwipeHelper;
 import com.android.systemui.statusbar.ActivatableNotificationView;
 import com.android.systemui.statusbar.DismissView;
+import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.ExpandableView;
 import com.android.systemui.statusbar.SpeedBumpView;
@@ -43,6 +44,7 @@
 import com.android.systemui.statusbar.stack.StackScrollState.ViewState;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 
 /**
  * A layout which handles a dynamic amount of notifications and presents them in a scrollable stack.
@@ -108,6 +110,7 @@
     private ArrayList<View> mSnappedBackChildren = new ArrayList<View>();
     private ArrayList<View> mDragAnimPendingChildren = new ArrayList<View>();
     private ArrayList<View> mChildrenChangingPositions = new ArrayList<View>();
+    private HashSet<View> mFromMoreCardAdditions = new HashSet<>();
     private ArrayList<AnimationEvent> mAnimationEvents
             = new ArrayList<AnimationEvent>();
     private ArrayList<View> mSwipedOutViews = new ArrayList<View>();
@@ -131,8 +134,10 @@
     private boolean mNeedsAnimation;
     private boolean mTopPaddingNeedsAnimation;
     private boolean mDimmedNeedsAnimation;
+    private boolean mHideSensitiveNeedsAnimation;
     private boolean mDarkNeedsAnimation;
     private boolean mActivateNeedsAnimation;
+    private boolean mGoToFullShadeNeedsAnimation;
     private boolean mIsExpanded = true;
     private boolean mChildrenUpdateRequested;
     private SpeedBumpView mSpeedBumpView;
@@ -141,6 +146,7 @@
     private boolean mExpandedInThisMotion;
     private boolean mScrollingEnabled;
     private DismissView mDismissView;
+    private EmptyShadeView mEmptyShadeView;
     private boolean mDismissAllInProgress;
 
     /**
@@ -175,6 +181,7 @@
     private boolean mInterceptDelegateEnabled;
     private boolean mDelegateToScrollView;
     private boolean mDisallowScrollingInThisMotion;
+    private long mGoToFullShadeDelay;
 
     private ViewTreeObserver.OnPreDrawListener mChildrenUpdater
             = new ViewTreeObserver.OnPreDrawListener() {
@@ -561,8 +568,11 @@
             float childTop = slidingChild.getTranslationY();
             float top = childTop + slidingChild.getClipTopAmount();
             float bottom = top + slidingChild.getActualHeight();
-            int left = slidingChild.getLeft();
-            int right = slidingChild.getRight();
+
+            // Allow the full width of this view to prevent gesture conflict on Keyguard (phone and
+            // camera affordance).
+            int left = 0;
+            int right = getWidth();
 
             if (touchY >= top && touchY <= bottom && touchX >= left && touchX <= right) {
                 return slidingChild;
@@ -1214,6 +1224,12 @@
                 count++;
             }
         }
+        if (mDismissView.willBeGone()) {
+            count--;
+        }
+        if (mEmptyShadeView.willBeGone()) {
+            count--;
+        }
         return count;
     }
 
@@ -1450,6 +1466,7 @@
                 return true;
             } else {
                 mChildrenToAddAnimated.remove(child);
+                mFromMoreCardAdditions.remove(child);
                 return false;
             }
         }
@@ -1506,7 +1523,7 @@
         super.onViewAdded(child);
         mStackScrollAlgorithm.notifyChildrenChanged(this);
         ((ExpandableView) child).setOnHeightChangedListener(this);
-        generateAddAnimation(child);
+        generateAddAnimation(child, false /* fromMoreCard */);
     }
 
     public void setAnimationsEnabled(boolean animationsEnabled) {
@@ -1521,11 +1538,15 @@
      * Generate an animation for an added child view.
      *
      * @param child The view to be added.
+     * @param fromMoreCard Whether this add is coming from the "more" card on lockscreen.
      */
-    public void generateAddAnimation(View child) {
+    public void generateAddAnimation(View child, boolean fromMoreCard) {
         if (mIsExpanded && mAnimationsEnabled && !mChangePositionInProgress) {
             // Generate Animations
             mChildrenToAddAnimated.add(child);
+            if (fromMoreCard) {
+                mFromMoreCardAdditions.add(child);
+            }
             mNeedsAnimation = true;
         }
     }
@@ -1556,11 +1577,13 @@
             mNeedsAnimation = false;
         }
         if (!mAnimationEvents.isEmpty() || isCurrentlyAnimating()) {
-            mStateAnimator.startAnimationForEvents(mAnimationEvents, mCurrentStackScrollState);
+            mStateAnimator.startAnimationForEvents(mAnimationEvents, mCurrentStackScrollState,
+                    mGoToFullShadeDelay);
             mAnimationEvents.clear();
         } else {
             applyCurrentState();
         }
+        mGoToFullShadeDelay = 0;
     }
 
     private void generateChildHierarchyEvents() {
@@ -1572,7 +1595,9 @@
         generateTopPaddingEvent();
         generateActivateEvent();
         generateDimmedEvent();
+        generateHideSensitiveEvent();
         generateDarkEvent();
+        generateGoToFullShadeEvent();
         mNeedsAnimation = false;
     }
 
@@ -1618,10 +1643,17 @@
 
     private void generateChildAdditionEvents() {
         for (View child : mChildrenToAddAnimated) {
-            mAnimationEvents.add(new AnimationEvent(child,
-                    AnimationEvent.ANIMATION_TYPE_ADD));
+            if (mFromMoreCardAdditions.contains(child)) {
+                mAnimationEvents.add(new AnimationEvent(child,
+                        AnimationEvent.ANIMATION_TYPE_ADD,
+                        StackStateAnimator.ANIMATION_DURATION_STANDARD));
+            } else {
+                mAnimationEvents.add(new AnimationEvent(child,
+                        AnimationEvent.ANIMATION_TYPE_ADD));
+            }
         }
         mChildrenToAddAnimated.clear();
+        mFromMoreCardAdditions.clear();
     }
 
     private void generateTopPaddingEvent() {
@@ -1648,6 +1680,14 @@
         mDimmedNeedsAnimation = false;
     }
 
+    private void generateHideSensitiveEvent() {
+        if (mHideSensitiveNeedsAnimation) {
+            mAnimationEvents.add(
+                    new AnimationEvent(null, AnimationEvent.ANIMATION_TYPE_HIDE_SENSITIVE));
+        }
+        mHideSensitiveNeedsAnimation = false;
+    }
+
     private void generateDarkEvent() {
         if (mDarkNeedsAnimation) {
             mAnimationEvents.add(
@@ -1656,6 +1696,14 @@
         mDarkNeedsAnimation = false;
     }
 
+    private void generateGoToFullShadeEvent() {
+        if (mGoToFullShadeNeedsAnimation) {
+            mAnimationEvents.add(
+                    new AnimationEvent(null, AnimationEvent.ANIMATION_TYPE_GO_TO_FULL_SHADE));
+        }
+        mGoToFullShadeNeedsAnimation = false;
+    }
+
     private boolean onInterceptTouchEventScroll(MotionEvent ev) {
         if (!isScrollingEnabled()) {
             return false;
@@ -1883,6 +1931,22 @@
         requestChildrenUpdate();
     }
 
+    public void setHideSensitive(boolean hideSensitive, boolean animate) {
+        if (hideSensitive != mAmbientState.isHideSensitive()) {
+            int childCount = getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                ExpandableView v = (ExpandableView) getChildAt(i);
+                v.setHideSensitiveForIntrinsicHeight(hideSensitive);
+            }
+            mAmbientState.setHideSensitive(hideSensitive);
+            if (animate && mAnimationsEnabled) {
+                mHideSensitiveNeedsAnimation = true;
+                mNeedsAnimation =  true;
+            }
+            requestChildrenUpdate();
+        }
+    }
+
     /**
      * See {@link AmbientState#setActivatedChild}.
      */
@@ -1919,19 +1983,21 @@
             if (visible) {
                 // Make invisible to ensure that the appear animation is played.
                 mSpeedBumpView.setInvisible();
-                if (!mIsExpansionChanging) {
-                    generateAddAnimation(mSpeedBumpView);
-                }
             } else {
-                mSpeedBumpView.performVisibilityAnimation(false);
+                // TODO: This doesn't really work, because the view is already set to GONE above.
                 generateRemoveAnimation(mSpeedBumpView);
             }
         }
     }
 
-    public void goToFullShade() {
+    public void goToFullShade(long delay) {
         updateSpeedBump(true /* visibility */);
         mDismissView.setInvisible();
+        mEmptyShadeView.setInvisible();
+        mGoToFullShadeNeedsAnimation = true;
+        mGoToFullShadeDelay = delay;
+        mNeedsAnimation =  true;
+        requestChildrenUpdate();
     }
 
     public void cancelExpandHelper() {
@@ -1982,6 +2048,38 @@
         addView(mDismissView);
     }
 
+    public void setEmptyShadeView(EmptyShadeView emptyShadeView) {
+        mEmptyShadeView = emptyShadeView;
+        addView(mEmptyShadeView);
+    }
+
+    public void updateEmptyShadeView(boolean visible) {
+        int oldVisibility = mEmptyShadeView.willBeGone() ? GONE : mEmptyShadeView.getVisibility();
+        int newVisibility = visible ? VISIBLE : GONE;
+        if (oldVisibility != newVisibility) {
+            if (oldVisibility == GONE) {
+                if (mEmptyShadeView.willBeGone()) {
+                    mEmptyShadeView.cancelAnimation();
+                } else {
+                    mEmptyShadeView.setInvisible();
+                    mEmptyShadeView.setVisibility(newVisibility);
+                }
+                mEmptyShadeView.setWillBeGone(false);
+                updateContentHeight();
+            } else {
+                mEmptyShadeView.setWillBeGone(true);
+                mEmptyShadeView.performVisibilityAnimation(false, new Runnable() {
+                    @Override
+                    public void run() {
+                        mEmptyShadeView.setVisibility(GONE);
+                        mEmptyShadeView.setWillBeGone(false);
+                        updateContentHeight();
+                    }
+                });
+            }
+        }
+    }
+
     public void updateDismissView(boolean visible) {
         int oldVisibility = mDismissView.willBeGone() ? GONE : mDismissView.getVisibility();
         int newVisibility = visible ? VISIBLE : GONE;
@@ -2025,6 +2123,22 @@
         return mDismissView.getHeight() + mPaddingBetweenElementsNormal;
     }
 
+    public float getBottomMostNotificationBottom() {
+        final int count = getChildCount();
+        float max = 0;
+        for (int childIdx = 0; childIdx < count; childIdx++) {
+            ExpandableView child = (ExpandableView) getChildAt(childIdx);
+            if (child.getVisibility() == GONE) {
+                continue;
+            }
+            float bottom = child.getTranslationY() + child.getActualHeight();
+            if (bottom > max) {
+                max = bottom;
+            }
+        }
+        return max + getTranslationY();
+    }
+
     /**
      * A listener that is notified when some child locations might have changed.
      */
@@ -2104,7 +2218,8 @@
 
                 // ANIMATION_TYPE_SNAP_BACK
                 new AnimationFilter()
-                        .animateAlpha(),
+                        .animateAlpha()
+                        .animateHeight(),
 
                 // ANIMATION_TYPE_ACTIVATED_CHILD
                 new AnimationFilter()
@@ -2128,6 +2243,21 @@
                 // ANIMATION_TYPE_DARK
                 new AnimationFilter()
                         .animateDark(),
+
+                // ANIMATION_TYPE_GO_TO_FULL_SHADE
+                new AnimationFilter()
+                        .animateAlpha()
+                        .animateHeight()
+                        .animateTopInset()
+                        .animateY()
+                        .animateDimmed()
+                        .animateScale()
+                        .animateZ()
+                        .hasDelays(),
+
+                // ANIMATION_TYPE_HIDE_SENSITIVE
+                new AnimationFilter()
+                        .animateHideSensitive(),
         };
 
         static int[] LENGTHS = new int[] {
@@ -2161,6 +2291,12 @@
 
                 // ANIMATION_TYPE_DARK
                 StackStateAnimator.ANIMATION_DURATION_STANDARD,
+
+                // ANIMATION_TYPE_GO_TO_FULL_SHADE
+                StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE,
+
+                // ANIMATION_TYPE_HIDE_SENSITIVE
+                StackStateAnimator.ANIMATION_DURATION_STANDARD,
         };
 
         static final int ANIMATION_TYPE_ADD = 0;
@@ -2173,6 +2309,8 @@
         static final int ANIMATION_TYPE_DIMMED = 7;
         static final int ANIMATION_TYPE_CHANGE_POSITION = 8;
         static final int ANIMATION_TYPE_DARK = 9;
+        static final int ANIMATION_TYPE_GO_TO_FULL_SHADE = 10;
+        static final int ANIMATION_TYPE_HIDE_SENSITIVE = 11;
 
         final long eventStartTime;
         final View changingView;
@@ -2182,24 +2320,33 @@
         View viewAfterChangingView;
 
         AnimationEvent(View view, int type) {
+            this(view, type, LENGTHS[type]);
+        }
+
+        AnimationEvent(View view, int type, long length) {
             eventStartTime = AnimationUtils.currentAnimationTimeMillis();
             changingView = view;
             animationType = type;
             filter = FILTERS[type];
-            length = LENGTHS[type];
+            this.length = length;
         }
 
         /**
          * Combines the length of several animation events into a single value.
          *
          * @param events The events of the lengths to combine.
-         * @return The combined length. This is just the maximum of all length.
+         * @return The combined length. Depending on the event types, this might be the maximum of
+         *         all events or the length of a specific event.
          */
         static long combineLength(ArrayList<AnimationEvent> events) {
             long length = 0;
             int size = events.size();
             for (int i = 0; i < size; i++) {
-                length = Math.max(length, events.get(i).length);
+                AnimationEvent event = events.get(i);
+                length = Math.max(length, event.length);
+                if (event.animationType == ANIMATION_TYPE_GO_TO_FULL_SHADE) {
+                    return event.length;
+                }
             }
             return length;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index fe2733b..ba3f339 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -159,7 +159,7 @@
         updateZValuesForState(resultState, algorithmState);
 
         handleDraggedViews(ambientState, resultState, algorithmState);
-        updateDimmedActivated(ambientState, resultState, algorithmState);
+        updateDimmedActivatedHideSensitive(ambientState, resultState, algorithmState);
         updateClipping(resultState, algorithmState);
         updateScrimAmount(resultState, algorithmState, ambientState.getScrimAmount());
         updateSpeedBumpState(resultState, algorithmState, ambientState.getSpeedBumpIndex());
@@ -251,12 +251,13 @@
     }
 
     /**
-     * Updates the dimmed and activated states of the children.
+     * Updates the dimmed, activated and hiding sensitive states of the children.
      */
-    private void updateDimmedActivated(AmbientState ambientState, StackScrollState resultState,
-            StackScrollAlgorithmState algorithmState) {
+    private void updateDimmedActivatedHideSensitive(AmbientState ambientState,
+            StackScrollState resultState, StackScrollAlgorithmState algorithmState) {
         boolean dimmed = ambientState.isDimmed();
         boolean dark = ambientState.isDark();
+        boolean hideSensitive = ambientState.isHideSensitive();
         View activatedChild = ambientState.getActivatedChild();
         int childCount = algorithmState.visibleChildren.size();
         for (int i = 0; i < childCount; i++) {
@@ -264,6 +265,7 @@
             StackScrollState.ViewState childViewState = resultState.getViewStateForView(child);
             childViewState.dimmed = dimmed;
             childViewState.dark = dark;
+            childViewState.hideSensitive = hideSensitive;
             boolean isActivatedChild = activatedChild == child;
             childViewState.scale = !dimmed || isActivatedChild
                     ? 1.0f
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
index 7b90a351..f7a2824 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
@@ -23,6 +23,7 @@
 
 import com.android.systemui.R;
 import com.android.systemui.statusbar.DismissView;
+import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.ExpandableView;
 import com.android.systemui.statusbar.SpeedBumpView;
 
@@ -157,6 +158,10 @@
                 // apply dark
                 child.setDark(state.dark, false /* animate */);
 
+                // apply hiding sensitive
+                child.setHideSensitive(
+                        state.hideSensitive, false /* animated */, 0 /* delay */, 0 /* duration */);
+
                 // apply speed bump state
                 child.setBelowSpeedBump(state.belowSpeedBump);
 
@@ -171,12 +176,16 @@
                 updateChildClip(child, newHeight, state.topOverLap);
 
                 if(child instanceof SpeedBumpView) {
-                    float lineEnd = newYTranslation + newHeight / 2;
-                    performSpeedBumpAnimation(i, (SpeedBumpView) child, lineEnd);
+                    performSpeedBumpAnimation(i, (SpeedBumpView) child, state, 0);
                 } else if (child instanceof DismissView) {
                     DismissView dismissView = (DismissView) child;
                     boolean visible = state.topOverLap < mClearAllTopPadding;
                     dismissView.performVisibilityAnimation(visible && !dismissView.willBeGone());
+                } else if (child instanceof EmptyShadeView) {
+                    EmptyShadeView emptyShadeView = (EmptyShadeView) child;
+                    boolean visible = state.topOverLap <= 0;
+                    emptyShadeView.performVisibilityAnimation(
+                            visible && !emptyShadeView.willBeGone());
                 }
             }
         }
@@ -197,12 +206,14 @@
         child.setClipBounds(mClipRect);
     }
 
-    private void performSpeedBumpAnimation(int i, SpeedBumpView speedBump, float speedBumpEnd) {
+    public void performSpeedBumpAnimation(int i, SpeedBumpView speedBump, ViewState state,
+            long delay) {
         View nextChild = getNextChildNotGone(i);
         if (nextChild != null) {
+            float lineEnd = state.yTranslation + state.height / 2;
             ViewState nextState = getViewStateForView(nextChild);
-            boolean startIsAboveNext = nextState.yTranslation > speedBumpEnd;
-            speedBump.animateDivider(startIsAboveNext, null /* onFinishedRunnable */);
+            boolean startIsAboveNext = nextState.yTranslation > lineEnd;
+            speedBump.animateDivider(startIsAboveNext, delay, null /* onFinishedRunnable */);
         }
     }
 
@@ -237,6 +248,7 @@
         float scale;
         boolean dimmed;
         boolean dark;
+        boolean hideSensitive;
         boolean belowSpeedBump;
 
         /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index 71524ec..afd7216 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -27,6 +27,7 @@
 
 import com.android.systemui.R;
 import com.android.systemui.statusbar.ExpandableView;
+import com.android.systemui.statusbar.SpeedBumpView;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -39,10 +40,12 @@
 public class StackStateAnimator {
 
     public static final int ANIMATION_DURATION_STANDARD = 360;
+    public static final int ANIMATION_DURATION_GO_TO_FULL_SHADE = 448;
     public static final int ANIMATION_DURATION_APPEAR_DISAPPEAR = 464;
     public static final int ANIMATION_DURATION_DIMMED_ACTIVATED = 220;
     public static final int ANIMATION_DELAY_PER_ELEMENT_INTERRUPTING = 80;
     public static final int ANIMATION_DELAY_PER_ELEMENT_MANUAL = 32;
+    public static final int ANIMATION_DELAY_PER_ELEMENT_GO_TO_FULL_SHADE = 48;
     private static final int DELAY_EFFECT_MAX_INDEX_DIFFERENCE = 2;
 
     private static final int TAG_ANIMATOR_TRANSLATION_Y = R.id.translation_y_animator_tag;
@@ -65,15 +68,19 @@
     private static final int TAG_START_TOP_INSET = R.id.top_inset_animator_start_value_tag;
 
     private final Interpolator mFastOutSlowInInterpolator;
+    private final int mGoToFullShadeAppearingTranslation;
     public NotificationStackScrollLayout mHostLayout;
     private ArrayList<NotificationStackScrollLayout.AnimationEvent> mNewEvents =
             new ArrayList<>();
     private ArrayList<View> mNewAddChildren = new ArrayList<>();
-    private Set<Animator> mAnimatorSet = new HashSet<Animator>();
-    private Stack<AnimatorListenerAdapter> mAnimationListenerPool
-            = new Stack<AnimatorListenerAdapter>();
+    private Set<Animator> mAnimatorSet = new HashSet<>();
+    private Stack<AnimatorListenerAdapter> mAnimationListenerPool = new Stack<>();
     private AnimationFilter mAnimationFilter = new AnimationFilter();
     private long mCurrentLength;
+    private long mCurrentAdditionalDelay;
+
+    /** The current index for the last child which was not added in this event set. */
+    private int mCurrentLastNotAddedIndex;
 
     private ValueAnimator mTopOverScrollAnimator;
     private ValueAnimator mBottomOverScrollAnimator;
@@ -82,6 +89,9 @@
         mHostLayout = hostLayout;
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(hostLayout.getContext(),
                 android.R.interpolator.fast_out_slow_in);
+        mGoToFullShadeAppearingTranslation =
+                hostLayout.getContext().getResources().getDimensionPixelSize(
+                        R.dimen.go_to_full_shade_appearing_translation);
     }
 
     public boolean isRunning() {
@@ -90,13 +100,15 @@
 
     public void startAnimationForEvents(
             ArrayList<NotificationStackScrollLayout.AnimationEvent> mAnimationEvents,
-            StackScrollState finalState) {
+            StackScrollState finalState, long additionalDelay) {
 
         processAnimationEvents(mAnimationEvents, finalState);
 
         int childCount = mHostLayout.getChildCount();
         mAnimationFilter.applyCombination(mNewEvents);
+        mCurrentAdditionalDelay = additionalDelay;
         mCurrentLength = NotificationStackScrollLayout.AnimationEvent.combineLength(mNewEvents);
+        mCurrentLastNotAddedIndex = findLastNotAddedIndex(finalState);
         for (int i = 0; i < childCount; i++) {
             final ExpandableView child = (ExpandableView) mHostLayout.getChildAt(i);
 
@@ -106,7 +118,7 @@
             }
 
             child.setClipBounds(null);
-            startAnimations(child, viewState, finalState);
+            startAnimations(child, viewState, finalState, i);
         }
         if (!isRunning()) {
             // no child has preformed any animation, lets finish
@@ -116,11 +128,27 @@
         mNewAddChildren.clear();
     }
 
+    private int findLastNotAddedIndex(StackScrollState finalState) {
+        int childCount = mHostLayout.getChildCount();
+        for (int i = childCount - 1; i >= 0; i--) {
+            final ExpandableView child = (ExpandableView) mHostLayout.getChildAt(i);
+
+            StackScrollState.ViewState viewState = finalState.getViewStateForView(child);
+            if (viewState == null || child.getVisibility() == View.GONE) {
+                continue;
+            }
+            if (!mNewAddChildren.contains(child)) {
+                return viewState.notGoneIndex;
+            }
+        }
+        return -1;
+    }
+
     /**
      * Start an animation to the given viewState
      */
     private void startAnimations(final ExpandableView child, StackScrollState.ViewState viewState,
-            StackScrollState finalState) {
+            StackScrollState finalState, int i) {
         int childVisibility = child.getVisibility();
         boolean wasVisible = childVisibility == View.VISIBLE;
         final float alpha = viewState.alpha;
@@ -139,38 +167,48 @@
         boolean isDelayRelevant = yTranslationChanging || zTranslationChanging || scaleChanging ||
                 alphaChanging || heightChanging || topInsetChanging;
         long delay = 0;
+        long duration = mCurrentLength;
         if (hasDelays && isDelayRelevant || wasAdded) {
-            delay = calculateChildAnimationDelay(viewState, finalState);
+            delay = mCurrentAdditionalDelay + calculateChildAnimationDelay(viewState, finalState);
+        }
+
+        if (wasAdded && mAnimationFilter.hasGoToFullShadeEvent) {
+            child.setTranslationY(child.getTranslationY() + mGoToFullShadeAppearingTranslation);
+            yTranslationChanging = true;
+            float longerDurationFactor = viewState.notGoneIndex - mCurrentLastNotAddedIndex;
+            longerDurationFactor = (float) Math.pow(longerDurationFactor, 0.7f);
+            duration = ANIMATION_DURATION_APPEAR_DISAPPEAR + 50 +
+                    (long) (100 * longerDurationFactor);
         }
 
         // start translationY animation
         if (yTranslationChanging) {
-            startYTranslationAnimation(child, viewState, delay);
+            startYTranslationAnimation(child, viewState, duration, delay);
         }
 
         // start translationZ animation
         if (zTranslationChanging) {
-            startZTranslationAnimation(child, viewState, delay);
+            startZTranslationAnimation(child, viewState, duration, delay);
         }
 
         // start scale animation
         if (scaleChanging) {
-            startScaleAnimation(child, viewState);
+            startScaleAnimation(child, viewState, duration);
         }
 
         // start alpha animation
         if (alphaChanging && child.getTranslationX() == 0) {
-            startAlphaAnimation(child, viewState, delay);
+            startAlphaAnimation(child, viewState, duration, delay);
         }
 
         // start height animation
         if (heightChanging) {
-            startHeightAnimation(child, viewState, delay);
+            startHeightAnimation(child, viewState, duration, delay);
         }
 
         // start top inset animation
         if (topInsetChanging) {
-            startInsetAnimation(child, viewState, delay);
+            startInsetAnimation(child, viewState, duration, delay);
         }
 
         // start dimmed animation
@@ -182,16 +220,27 @@
         // apply speed bump state
         child.setBelowSpeedBump(viewState.belowSpeedBump);
 
+        // start hiding sensitive animation
+        child.setHideSensitive(viewState.hideSensitive,
+                mAnimationFilter.animateHideSensitive && !wasAdded, delay, duration);
+
         // apply scrimming
         child.setScrimAmount(viewState.scrimAmount);
 
         if (wasAdded) {
-            child.performAddAnimation(delay);
+            child.performAddAnimation(delay, mCurrentLength);
+        }
+        if (child instanceof SpeedBumpView) {
+            finalState.performSpeedBumpAnimation(i, (SpeedBumpView) child, viewState,
+                    delay + duration);
         }
     }
 
     private long calculateChildAnimationDelay(StackScrollState.ViewState viewState,
             StackScrollState finalState) {
+        if (mAnimationFilter.hasGoToFullShadeEvent) {
+            return calculateDelayGoToFullShade(viewState);
+        }
         long minDelay = 0;
         for (NotificationStackScrollLayout.AnimationEvent event : mNewEvents) {
             long delayPerElement = ANIMATION_DELAY_PER_ELEMENT_INTERRUPTING;
@@ -236,8 +285,14 @@
         return minDelay;
     }
 
+    private long calculateDelayGoToFullShade(StackScrollState.ViewState viewState) {
+        float index = viewState.notGoneIndex;
+        index = (float) Math.pow(index, 0.7f);
+        return (long) (index * ANIMATION_DELAY_PER_ELEMENT_GO_TO_FULL_SHADE);
+    }
+
     private void startHeightAnimation(final ExpandableView child,
-            StackScrollState.ViewState viewState, long delay) {
+            StackScrollState.ViewState viewState, long duration, long delay) {
         Integer previousStartValue = getChildTag(child, TAG_START_HEIGHT);
         Integer previousEndValue = getChildTag(child, TAG_END_HEIGHT);
         int newEndValue = viewState.height;
@@ -274,7 +329,7 @@
             }
         });
         animator.setInterpolator(mFastOutSlowInInterpolator);
-        long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator);
+        long newDuration = cancelAnimatorAndGetNewDuration(duration, previousAnimator);
         animator.setDuration(newDuration);
         if (delay > 0 && (previousAnimator == null || !previousAnimator.isRunning())) {
             animator.setStartDelay(delay);
@@ -296,7 +351,7 @@
     }
 
     private void startInsetAnimation(final ExpandableView child,
-            StackScrollState.ViewState viewState, long delay) {
+            StackScrollState.ViewState viewState, long duration, long delay) {
         Integer previousStartValue = getChildTag(child, TAG_START_TOP_INSET);
         Integer previousEndValue = getChildTag(child, TAG_END_TOP_INSET);
         int newEndValue = viewState.clipTopAmount;
@@ -332,7 +387,7 @@
             }
         });
         animator.setInterpolator(mFastOutSlowInInterpolator);
-        long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator);
+        long newDuration = cancelAnimatorAndGetNewDuration(duration, previousAnimator);
         animator.setDuration(newDuration);
         if (delay > 0 && (previousAnimator == null || !previousAnimator.isRunning())) {
             animator.setStartDelay(delay);
@@ -354,7 +409,7 @@
     }
 
     private void startAlphaAnimation(final ExpandableView child,
-            final StackScrollState.ViewState viewState, long delay) {
+            final StackScrollState.ViewState viewState, long duration, long delay) {
         Float previousStartValue = getChildTag(child,TAG_START_ALPHA);
         Float previousEndValue = getChildTag(child,TAG_END_ALPHA);
         final float newEndValue = viewState.alpha;
@@ -413,7 +468,7 @@
                 mWasCancelled = false;
             }
         });
-        long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator);
+        long newDuration = cancelAnimatorAndGetNewDuration(duration, previousAnimator);
         animator.setDuration(newDuration);
         if (delay > 0 && (previousAnimator == null || !previousAnimator.isRunning())) {
             animator.setStartDelay(delay);
@@ -433,7 +488,7 @@
     }
 
     private void startZTranslationAnimation(final ExpandableView child,
-            final StackScrollState.ViewState viewState, long delay) {
+            final StackScrollState.ViewState viewState, long duration, long delay) {
         Float previousStartValue = getChildTag(child,TAG_START_TRANSLATION_Z);
         Float previousEndValue = getChildTag(child,TAG_END_TRANSLATION_Z);
         float newEndValue = viewState.zTranslation;
@@ -463,7 +518,7 @@
         ObjectAnimator animator = ObjectAnimator.ofFloat(child, View.TRANSLATION_Z,
                 child.getTranslationZ(), newEndValue);
         animator.setInterpolator(mFastOutSlowInInterpolator);
-        long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator);
+        long newDuration = cancelAnimatorAndGetNewDuration(duration, previousAnimator);
         animator.setDuration(newDuration);
         if (delay > 0 && (previousAnimator == null || !previousAnimator.isRunning())) {
             animator.setStartDelay(delay);
@@ -485,7 +540,7 @@
     }
 
     private void startYTranslationAnimation(final ExpandableView child,
-            StackScrollState.ViewState viewState, long delay) {
+            StackScrollState.ViewState viewState, long duration, long delay) {
         Float previousStartValue = getChildTag(child,TAG_START_TRANSLATION_Y);
         Float previousEndValue = getChildTag(child,TAG_END_TRANSLATION_Y);
         float newEndValue = viewState.yTranslation;
@@ -516,7 +571,7 @@
         ObjectAnimator animator = ObjectAnimator.ofFloat(child, View.TRANSLATION_Y,
                 child.getTranslationY(), newEndValue);
         animator.setInterpolator(mFastOutSlowInInterpolator);
-        long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator);
+        long newDuration = cancelAnimatorAndGetNewDuration(duration, previousAnimator);
         animator.setDuration(newDuration);
         if (delay > 0 && (previousAnimator == null || !previousAnimator.isRunning())) {
             animator.setStartDelay(delay);
@@ -538,7 +593,7 @@
     }
 
     private void startScaleAnimation(final ExpandableView child,
-            StackScrollState.ViewState viewState) {
+            StackScrollState.ViewState viewState, long duration) {
         Float previousStartValue = getChildTag(child, TAG_START_SCALE);
         Float previousEndValue = getChildTag(child, TAG_END_SCALE);
         float newEndValue = viewState.scale;
@@ -573,7 +628,7 @@
                 PropertyValuesHolder.ofFloat(View.SCALE_Y, child.getScaleY(), newEndValue);
         ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(child, holderX, holderY);
         animator.setInterpolator(mFastOutSlowInInterpolator);
-        long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator);
+        long newDuration = cancelAnimatorAndGetNewDuration(duration, previousAnimator);
         animator.setDuration(newDuration);
         animator.addListener(getGlobalAnimationFinishedListener());
         // remove the tag when the animation is finished
@@ -637,11 +692,12 @@
     /**
      * Cancel the previous animator and get the duration of the new animation.
      *
+     * @param duration the new duration
      * @param previousAnimator the animator which was running before
      * @return the new duration
      */
-    private long cancelAnimatorAndGetNewDuration(ValueAnimator previousAnimator) {
-        long newDuration = mCurrentLength;
+    private long cancelAnimatorAndGetNewDuration(long duration, ValueAnimator previousAnimator) {
+        long newDuration = duration;
         if (previousAnimator != null) {
             // We take either the desired length of the new animation or the remaining time of
             // the previous animator, whichever is longer.
@@ -710,7 +766,8 @@
                     translationDirection = Math.max(Math.min(translationDirection, 1.0f),-1.0f);
 
                 }
-                changingView.performRemoveAnimation(translationDirection, new Runnable() {
+                changingView.performRemoveAnimation(ANIMATION_DURATION_APPEAR_DISAPPEAR,
+                        translationDirection, new Runnable() {
                     @Override
                     public void run() {
                         // remove the temporary overlay
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index a123bf7..049add5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -99,6 +99,14 @@
     public void buzzBeepBlinked() {
     }
 
+    @Override // CommandQueue
+    public void notificationLightOff() {
+    }
+
+    @Override // CommandQueue
+    public void notificationLightPulse(int argb, int onMillis, int offMillis) {
+    }
+
     @Override
     protected WindowManager.LayoutParams getSearchLayoutParams(
             LayoutParams layoutParams) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
index 149d09a..3a63a79 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
@@ -24,6 +24,7 @@
 import android.content.DialogInterface.OnDismissListener;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.PixelFormat;
@@ -44,7 +45,7 @@
 import android.provider.Settings.Global;
 import android.util.Log;
 import android.util.SparseArray;
-import android.view.Gravity;
+import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -249,6 +250,8 @@
         private final VolumePanel mVolumePanel;
         private final AudioManager mAudioManager;
 
+        private boolean mNewVolumeUp;
+
         SafetyWarning(Context context, VolumePanel volumePanel, AudioManager audioManager) {
             super(context);
             mContext = context;
@@ -267,6 +270,24 @@
         }
 
         @Override
+        public boolean onKeyDown(int keyCode, KeyEvent event) {
+            if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && event.getRepeatCount() == 0) {
+                mNewVolumeUp = true;
+            }
+            return super.onKeyDown(keyCode, event);
+        }
+
+        @Override
+        public boolean onKeyUp(int keyCode, KeyEvent event) {
+            if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && mNewVolumeUp) {
+                if (LOGD) Log.d(TAG, "Confirmed warning via VOLUME_UP");
+                mAudioManager.disableSafeMediaVolume();
+                dismiss();
+            }
+            return super.onKeyUp(keyCode, event);
+        }
+
+        @Override
         public void onClick(DialogInterface dialog, int which) {
             mAudioManager.disableSafeMediaVolume();
         }
@@ -334,23 +355,8 @@
             }
         };
 
-        // Change some window properties
         final Window window = mDialog.getWindow();
-        final LayoutParams lp = window.getAttributes();
-        lp.token = null;
-        // Offset from the top
-        lp.y = res.getDimensionPixelOffset(com.android.systemui.R.dimen.volume_panel_top);
-        lp.type = LayoutParams.TYPE_STATUS_BAR_PANEL;
-        lp.format = PixelFormat.TRANSLUCENT;
-        lp.windowAnimations = com.android.systemui.R.style.VolumePanelAnimation;
-        lp.gravity = Gravity.TOP;
-        window.setAttributes(lp);
-        window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
         window.requestFeature(Window.FEATURE_NO_TITLE);
-        window.addFlags(LayoutParams.FLAG_NOT_FOCUSABLE
-                | LayoutParams.FLAG_NOT_TOUCH_MODAL
-                | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
-                | LayoutParams.FLAG_HARDWARE_ACCELERATED);
         mDialog.setCanceledOnTouchOutside(true);
         mDialog.setContentView(com.android.systemui.R.layout.volume_dialog);
         mDialog.setOnDismissListener(new OnDismissListener() {
@@ -363,9 +369,24 @@
         });
 
         mDialog.create();
-        // temporary workaround, until we support window-level shadows
-        mDialog.getWindow().setBackgroundDrawable(new ColorDrawable(0x00000000));
 
+        final LayoutParams lp = window.getAttributes();
+        lp.token = null;
+        lp.y = res.getDimensionPixelOffset(com.android.systemui.R.dimen.volume_panel_top);
+        lp.type = LayoutParams.TYPE_STATUS_BAR_PANEL;
+        lp.format = PixelFormat.TRANSLUCENT;
+        lp.windowAnimations = com.android.systemui.R.style.VolumePanelAnimation;
+        lp.setTitle(TAG);
+        window.setAttributes(lp);
+
+        updateWidth();
+
+        window.setBackgroundDrawable(new ColorDrawable(0x00000000));
+        window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+        window.addFlags(LayoutParams.FLAG_NOT_FOCUSABLE
+                | LayoutParams.FLAG_NOT_TOUCH_MODAL
+                | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                | LayoutParams.FLAG_HARDWARE_ACCELERATED);
         mView = window.findViewById(R.id.content);
         mView.setOnTouchListener(new View.OnTouchListener() {
             @Override
@@ -395,6 +416,19 @@
         registerReceiver();
     }
 
+    public void onConfigurationChanged(Configuration newConfig) {
+        updateWidth();
+    }
+
+    private void updateWidth() {
+        final Resources res = mContext.getResources();
+        final LayoutParams lp = mDialog.getWindow().getAttributes();
+        lp.width = res.getDimensionPixelSize(com.android.systemui.R.dimen.notification_panel_width);
+        lp.gravity =
+                res.getInteger(com.android.systemui.R.integer.notification_panel_layout_gravity);
+        mDialog.getWindow().setAttributes(lp);
+    }
+
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("VolumePanel state:");
         pw.print("  mTag="); pw.println(mTag);
@@ -659,15 +693,15 @@
             // never disable touch interactions for remote playback, the muting is not tied to
             // the state of the phone.
             sc.seekbarView.setEnabled(!fixedVolume);
-        } else if (fixedVolume ||
-                        (sc.streamType != mAudioManager.getMasterStreamType() && muted) ||
-                        (sSafetyWarning != null)) {
-            sc.seekbarView.setEnabled(false);
         } else if (isRinger && mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT) {
             sc.seekbarView.setEnabled(false);
             sc.icon.setEnabled(false);
             sc.icon.setAlpha(mDisabledAlpha);
             sc.icon.setClickable(false);
+        } else if (fixedVolume ||
+                (sc.streamType != mAudioManager.getMasterStreamType() && muted) ||
+                (sSafetyWarning != null)) {
+            sc.seekbarView.setEnabled(false);
         } else {
             sc.seekbarView.setEnabled(true);
             sc.icon.setEnabled(true);
@@ -995,7 +1029,6 @@
             int stream = (streamType == AudioService.STREAM_REMOTE_MUSIC) ? -1 : streamType;
             // when the stream is for remote playback, use -1 to reset the stream type evaluation
             mAudioManager.forceVolumeControlStream(stream);
-
             mDialog.show();
             if (mCallback != null) {
                 mCallback.onVisible(true);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
index cc351f9..04a3b88 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
@@ -3,6 +3,7 @@
 import android.app.ActivityManagerNative;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Configuration;
 import android.database.ContentObserver;
 import android.media.AudioManager;
 import android.media.IRemoteVolumeController;
@@ -73,6 +74,14 @@
     }
 
     @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        if (mPanel != null) {
+            mPanel.onConfigurationChanged(newConfig);
+        }
+    }
+
+    @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (mPanel != null) {
             mPanel.dump(fd, pw, args);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 191f993..0d837c7 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -284,14 +284,12 @@
         final boolean zenOff = zen == Global.ZEN_MODE_OFF;
         final boolean zenImportant = zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         final boolean zenNone = zen == Global.ZEN_MODE_NO_INTERRUPTIONS;
-        final boolean foreverSelected = mExitConditionId == null;
         final boolean hasNextAlarm = mNextAlarm != 0;
         final boolean expanded = !mHidden && mExpanded;
         final boolean showAlarmWarning = zenNone && expanded && hasNextAlarm;
 
         mZenButtons.setVisibility(mHidden ? GONE : VISIBLE);
-        mZenSubhead.setVisibility(!mHidden && !zenOff && (expanded || !foreverSelected) ? VISIBLE
-                : GONE);
+        mZenSubhead.setVisibility(!mHidden && !zenOff ? VISIBLE : GONE);
         mZenSubheadExpanded.setVisibility(expanded ? VISIBLE : GONE);
         mZenSubheadCollapsed.setVisibility(!expanded ? VISIBLE : GONE);
         mMoreSettings.setVisibility(zenImportant && expanded ? VISIBLE : GONE);
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 324f536..14f6c5a 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -279,6 +279,7 @@
     int[] mNavigationBarHeightForRotation = new int[4];
     int[] mNavigationBarWidthForRotation = new int[4];
 
+    boolean mBootMessageNeedsHiding;
     KeyguardServiceDelegate mKeyguardDelegate;
     // The following are only accessed on the mHandler thread.
     boolean mKeyguardDrawComplete;
@@ -537,6 +538,7 @@
     private static final int MSG_WAKING_UP = 8;
     private static final int MSG_DISPATCH_SHOW_RECENTS = 9;
     private static final int MSG_DISPATCH_SHOW_GLOBAL_ACTIONS = 10;
+    private static final int MSG_HIDE_BOOT_MESSAGE = 11;
 
     private class PolicyHandler extends Handler {
         @Override
@@ -579,6 +581,9 @@
                 case MSG_WAKING_UP:
                     handleWakingUp((ScreenOnListener) msg.obj);
                     break;
+                case MSG_HIDE_BOOT_MESSAGE:
+                    handleHideBootMessage();
+                    break;
             }
         }
     }
@@ -1096,9 +1101,7 @@
         initializeHdmiState();
 
         // Match current screen state.
-        if (mPowerManager.isInteractive()) {
-            wakingUp(null);
-        } else {
+        if (!mPowerManager.isInteractive()) {
             goingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
         }
     }
@@ -2138,7 +2141,7 @@
 
         // Cancel any pending meta actions if we see any other keys being pressed between the down
         // of the meta key and its corresponding up.
-        if (mPendingMetaAction && keyCode != KeyEvent.KEYCODE_META_LEFT) {
+        if (mPendingMetaAction && KeyEvent.isMetaKey(keyCode)) {
             mPendingMetaAction = false;
         }
 
@@ -2343,11 +2346,10 @@
                         UserHandle.CURRENT_OR_SELF);
             }
             return -1;
-        } else if (keyCode == KeyEvent.KEYCODE_META_LEFT) {
+        } else if (KeyEvent.isMetaKey(keyCode)) {
             if (down) {
                 mPendingMetaAction = true;
             } else if (mPendingMetaAction) {
-                mPendingMetaAction = false;
                 launchAssistAction();
             }
             return -1;
@@ -2426,7 +2428,9 @@
         if (down && repeatCount == 0 && keyCode == KeyEvent.KEYCODE_TAB) {
             if (mRecentAppsHeldModifiers == 0 && !keyguardOn) {
                 final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK;
-                if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)) {
+                if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)
+                        || KeyEvent.metaStateHasModifiers(
+                        shiftlessModifiers, KeyEvent.META_META_ON)) {
                     mRecentAppsHeldModifiers = shiftlessModifiers;
                     showRecentApps(true);
                     return -1;
@@ -2435,7 +2439,7 @@
         } else if (!down && mRecentAppsHeldModifiers != 0
                 && (metaState & mRecentAppsHeldModifiers) == 0) {
             mRecentAppsHeldModifiers = 0;
-            hideRecentApps(true);
+            hideRecentApps(true, false);
         }
 
         // Handle keyboard language switching.
@@ -2459,7 +2463,7 @@
         }
 
         // Reserve all the META modifier combos for system behavior
-        if ((metaState & KeyEvent.META_META_LEFT_ON) != 0) {
+        if ((metaState & KeyEvent.META_META_ON) != 0) {
             return -1;
         }
 
@@ -2654,12 +2658,12 @@
         }
     }
 
-    private void hideRecentApps(boolean triggeredFromAltTab) {
+    private void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHome) {
         mPreloadedRecentApps = false; // preloading no longer needs to be canceled
         try {
             IStatusBarService statusbar = getStatusBarService();
             if (statusbar != null) {
-                statusbar.hideRecentApps(triggeredFromAltTab);
+                statusbar.hideRecentApps(triggeredFromAltTab, triggeredFromHome);
             }
         } catch (RemoteException e) {
             Slog.e(TAG, "RemoteException when closing recent apps", e);
@@ -2701,7 +2705,7 @@
                 // Hide Recents and notify it to launch Home
                 awakenDreams();
                 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
-                hideRecentApps(false);
+                hideRecentApps(false, true);
             } else {
                 // Otherwise, just launch Home
                 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
@@ -4649,6 +4653,26 @@
         }
 
         setKeyguardDrawn();
+
+        if (mBootMessageNeedsHiding) {
+            handleHideBootMessage();
+            mBootMessageNeedsHiding = false;
+        }
+    }
+
+    private void handleHideBootMessage() {
+        if (mBootMsgDialog == null) {
+            if (DEBUG_WAKEUP) Slog.d(TAG, "handleHideBootMessage: boot message not up");
+            return;
+        }
+        if (!mKeyguardDrawComplete || !mWindowManagerDrawComplete) {
+            if (DEBUG_WAKEUP) Slog.d(TAG, "handleHideBootMessage: deferring until keyguard ready");
+            mBootMessageNeedsHiding = true;
+            return;
+        }
+        if (DEBUG_WAKEUP) Slog.d(TAG, "handleHideBootMessage: dismissing");
+        mBootMsgDialog.dismiss();
+        mBootMsgDialog = null;
     }
 
     @Override
@@ -5106,14 +5130,7 @@
     /** {@inheritDoc} */
     @Override
     public void hideBootMessages() {
-        mHandler.post(new Runnable() {
-            @Override public void run() {
-                if (mBootMsgDialog != null) {
-                    mBootMsgDialog.dismiss();
-                    mBootMsgDialog = null;
-                }
-            }
-        });
+        mHandler.sendEmptyMessage(MSG_HIDE_BOOT_MESSAGE);
     }
 
     /** {@inheritDoc} */
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
index 2fa23c9..3f95427 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
@@ -16,421 +16,32 @@
 
 package com.android.server.appwidget;
 
-import android.app.ActivityManager;
-import android.appwidget.AppWidgetProviderInfo;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.widget.RemoteViews;
 
-import com.android.internal.appwidget.IAppWidgetHost;
-import com.android.internal.appwidget.IAppWidgetService;
-import com.android.internal.os.BackgroundThread;
-import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.AppWidgetBackupBridge;
-import com.android.server.WidgetBackupProvider;
 import com.android.server.SystemService;
 
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.List;
-
-
 /**
  * SystemService that publishes an IAppWidgetService.
  */
-public class AppWidgetService extends SystemService implements WidgetBackupProvider {
-
-    static final String TAG = "AppWidgetService";
-
-    final Context mContext;
-    final Handler mSaveStateHandler;
-
-    final SparseArray<AppWidgetServiceImpl> mAppWidgetServices;
+public class AppWidgetService extends SystemService {
+    private final AppWidgetServiceImpl mImpl;
 
     public AppWidgetService(Context context) {
         super(context);
-        mContext = context;
-
-        mSaveStateHandler = BackgroundThread.getHandler();
-
-        mAppWidgetServices = new SparseArray<AppWidgetServiceImpl>(5);
-        AppWidgetServiceImpl primary = new AppWidgetServiceImpl(context, 0, mSaveStateHandler);
-        mAppWidgetServices.append(0, primary);
+        mImpl = new AppWidgetServiceImpl(context);
     }
 
     @Override
     public void onStart() {
-        publishBinderService(Context.APPWIDGET_SERVICE, mServiceImpl);
-        AppWidgetBackupBridge.register(this);
+        publishBinderService(Context.APPWIDGET_SERVICE, mImpl);
+        AppWidgetBackupBridge.register(mImpl);
     }
 
     @Override
     public void onBootPhase(int phase) {
         if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
-            mServiceImpl.systemRunning(isSafeMode());
+            mImpl.setSafeMode(isSafeMode());
         }
     }
-
-
-    // backup <-> app widget service bridge surface
-    @Override
-    public List<String> getWidgetParticipants(int userId) {
-        return mServiceImpl.getWidgetParticipants(userId);
-    }
-
-    @Override
-    public byte[] getWidgetState(String packageName, int userId) {
-        return mServiceImpl.getWidgetState(packageName, userId);
-    }
-
-    @Override
-    public void restoreStarting(int userId) {
-        mServiceImpl.restoreStarting(userId);
-    }
-
-    @Override
-    public void restoreWidgetState(String packageName, byte[] restoredState, int userId) {
-        mServiceImpl.restoreWidgetState(packageName, restoredState, userId);
-    }
-
-    @Override
-    public void restoreFinished(int userId) {
-        mServiceImpl.restoreFinished(userId);
-    }
-
-
-    // implementation entry point and binder service
-    private final AppWidgetServiceStub mServiceImpl = new AppWidgetServiceStub();
-
-    class AppWidgetServiceStub extends IAppWidgetService.Stub {
-
-        private boolean mSafeMode;
-
-        public void systemRunning(boolean safeMode) {
-            mSafeMode = safeMode;
-
-            mAppWidgetServices.get(0).systemReady(safeMode);
-
-            // Register for the boot completed broadcast, so we can send the
-            // ENABLE broacasts. If we try to send them now, they time out,
-            // because the system isn't ready to handle them yet.
-            IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
-            filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
-            mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
-                    filter, null, null);
-
-            // Register for configuration changes so we can update the names
-            // of the widgets when the locale changes.
-            mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
-                    new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED), null, null);
-
-            // Register for broadcasts about package install, etc., so we can
-            // update the provider list.
-            filter.addAction(Intent.ACTION_PACKAGE_ADDED);
-            filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
-            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-            filter.addDataScheme("package");
-            mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
-                    filter, null, null);
-            // Register for events related to sdcard installation.
-            IntentFilter sdFilter = new IntentFilter();
-            sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
-            sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
-            mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
-                    sdFilter, null, null);
-
-            IntentFilter userFilter = new IntentFilter();
-            userFilter.addAction(Intent.ACTION_USER_REMOVED);
-            userFilter.addAction(Intent.ACTION_USER_STOPPING);
-            mContext.registerReceiver(new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
-                        onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
-                                UserHandle.USER_NULL));
-                    } else if (Intent.ACTION_USER_STOPPING.equals(intent.getAction())) {
-                        onUserStopping(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
-                                UserHandle.USER_NULL));
-                    }
-                }
-            }, userFilter);
-        }
-
-        @Override
-        public int allocateAppWidgetId(String packageName, int hostId, int userId)
-                throws RemoteException {
-            return getImplForUser(userId).allocateAppWidgetId(packageName, hostId);
-        }
-
-        @Override
-        public int[] getAppWidgetIdsForHost(int hostId, int userId) throws RemoteException {
-            return getImplForUser(userId).getAppWidgetIdsForHost(hostId);
-        }
-
-        @Override
-        public void deleteAppWidgetId(int appWidgetId, int userId) throws RemoteException {
-            getImplForUser(userId).deleteAppWidgetId(appWidgetId);
-        }
-
-        @Override
-        public void deleteHost(int hostId, int userId) throws RemoteException {
-            getImplForUser(userId).deleteHost(hostId);
-        }
-
-        @Override
-        public void deleteAllHosts(int userId) throws RemoteException {
-            getImplForUser(userId).deleteAllHosts();
-        }
-
-        @Override
-        public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options,
-                int userId) throws RemoteException {
-            getImplForUser(userId).bindAppWidgetId(appWidgetId, provider, options);
-        }
-
-        @Override
-        public boolean bindAppWidgetIdIfAllowed(
-                String packageName, int appWidgetId, ComponentName provider, Bundle options,
-                int userId) throws RemoteException {
-            return getImplForUser(userId).bindAppWidgetIdIfAllowed(
-                    packageName, appWidgetId, provider, options);
-        }
-
-        @Override
-        public boolean hasBindAppWidgetPermission(String packageName, int userId)
-                throws RemoteException {
-            return getImplForUser(userId).hasBindAppWidgetPermission(packageName);
-        }
-
-        @Override
-        public void setBindAppWidgetPermission(String packageName, boolean permission, int userId)
-                throws RemoteException {
-            getImplForUser(userId).setBindAppWidgetPermission(packageName, permission);
-        }
-
-        @Override
-        public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection,
-                int userId) throws RemoteException {
-            getImplForUser(userId).bindRemoteViewsService(appWidgetId, intent, connection);
-        }
-
-        @Override
-        public int[] startListening(IAppWidgetHost host, String packageName, int hostId,
-                List<RemoteViews> updatedViews, int userId) throws RemoteException {
-            return getImplForUser(userId).startListening(host, packageName, hostId, updatedViews);
-        }
-
-        public void onUserRemoved(int userId) {
-            if (userId < 1) return;
-            synchronized (mAppWidgetServices) {
-                AppWidgetServiceImpl impl = mAppWidgetServices.get(userId);
-                mAppWidgetServices.remove(userId);
-
-                if (impl == null) {
-                    AppWidgetServiceImpl.getSettingsFile(userId).delete();
-                } else {
-                    impl.onUserRemoved();
-                }
-            }
-        }
-
-        public void onUserStopping(int userId) {
-            if (userId < 1) return;
-            synchronized (mAppWidgetServices) {
-                AppWidgetServiceImpl impl = mAppWidgetServices.get(userId);
-                if (impl != null) {
-                    mAppWidgetServices.remove(userId);
-                    impl.onUserStopping();
-                }
-            }
-        }
-
-
-        // support of the widget/backup bridge
-        public List<String> getWidgetParticipants(int userId) {
-            return getImplForUser(userId).getWidgetParticipants();
-        }
-
-        public byte[] getWidgetState(String packageName, int userId) {
-            return getImplForUser(userId).getWidgetState(packageName);
-        }
-
-        public void restoreStarting(int userId) {
-            getImplForUser(userId).restoreStarting();
-        }
-
-        public void restoreWidgetState(String packageName, byte[] restoredState, int userId) {
-            getImplForUser(userId).restoreWidgetState(packageName, restoredState);
-        }
-
-        public void restoreFinished(int userId) {
-            getImplForUser(userId).restoreFinished();
-        }
-
-
-        private void checkPermission(int userId) {
-            int realUserId = ActivityManager.handleIncomingUser(
-                    Binder.getCallingPid(),
-                    Binder.getCallingUid(),
-                    userId,
-                    false, /* allowAll */
-                    true, /* requireFull */
-                    this.getClass().getSimpleName(),
-                    this.getClass().getPackage().getName());
-        }
-
-        private AppWidgetServiceImpl getImplForUser(int userId) {
-            checkPermission(userId);
-            boolean sendInitial = false;
-            AppWidgetServiceImpl service;
-            synchronized (mAppWidgetServices) {
-                service = mAppWidgetServices.get(userId);
-                if (service == null) {
-                    Slog.i(TAG, "Unable to find AppWidgetServiceImpl for user " + userId
-                            + ", adding");
-                    // TODO: Verify that it's a valid user
-                    service = new AppWidgetServiceImpl(mContext, userId, mSaveStateHandler);
-                    service.systemReady(mSafeMode);
-                    // Assume that BOOT_COMPLETED was received, as this is a non-primary user.
-                    mAppWidgetServices.append(userId, service);
-                    sendInitial = true;
-                }
-            }
-            if (sendInitial) {
-                service.sendInitialBroadcasts();
-            }
-            return service;
-        }
-
-        @Override
-        public int[] getAppWidgetIds(ComponentName provider, int userId) throws RemoteException {
-            return getImplForUser(userId).getAppWidgetIds(provider);
-        }
-
-        @Override
-        public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId, int userId)
-                throws RemoteException {
-            return getImplForUser(userId).getAppWidgetInfo(appWidgetId);
-        }
-
-        @Override
-        public RemoteViews getAppWidgetViews(int appWidgetId, int userId) throws RemoteException {
-            return getImplForUser(userId).getAppWidgetViews(appWidgetId);
-        }
-
-        @Override
-        public void updateAppWidgetOptions(int appWidgetId, Bundle options, int userId) {
-            getImplForUser(userId).updateAppWidgetOptions(appWidgetId, options);
-        }
-
-        @Override
-        public Bundle getAppWidgetOptions(int appWidgetId, int userId) {
-            return getImplForUser(userId).getAppWidgetOptions(appWidgetId);
-        }
-
-        @Override
-        public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter, int userId)
-                throws RemoteException {
-            return getImplForUser(userId).getInstalledProviders(categoryFilter);
-        }
-
-        @Override
-        public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId, int userId)
-                throws RemoteException {
-            getImplForUser(userId).notifyAppWidgetViewDataChanged(
-                    appWidgetIds, viewId);
-        }
-
-        @Override
-        public void partiallyUpdateAppWidgetIds(int[] appWidgetIds, RemoteViews views, int userId)
-                throws RemoteException {
-            getImplForUser(userId).partiallyUpdateAppWidgetIds(
-                    appWidgetIds, views);
-        }
-
-        @Override
-        public void stopListening(int hostId, int userId) throws RemoteException {
-            getImplForUser(userId).stopListening(hostId);
-        }
-
-        @Override
-        public void unbindRemoteViewsService(int appWidgetId, Intent intent, int userId)
-                throws RemoteException {
-            getImplForUser(userId).unbindRemoteViewsService(
-                    appWidgetId, intent);
-        }
-
-        @Override
-        public void updateAppWidgetIds(int[] appWidgetIds, RemoteViews views, int userId)
-                throws RemoteException {
-            getImplForUser(userId).updateAppWidgetIds(appWidgetIds, views);
-        }
-
-        @Override
-        public void updateAppWidgetProvider(ComponentName provider, RemoteViews views, int userId)
-                throws RemoteException {
-            getImplForUser(userId).updateAppWidgetProvider(provider, views);
-        }
-
-        @Override
-        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
-
-            // Dump the state of all the app widget providers
-            synchronized (mAppWidgetServices) {
-                IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
-                for (int i = 0; i < mAppWidgetServices.size(); i++) {
-                    pw.println("User: " + mAppWidgetServices.keyAt(i));
-                    ipw.increaseIndent();
-                    AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i);
-                    service.dump(fd, ipw, args);
-                    ipw.decreaseIndent();
-                }
-            }
-        }
-
-        BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-            public void onReceive(Context context, Intent intent) {
-                String action = intent.getAction();
-                // Slog.d(TAG, "received " + action);
-                if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
-                    int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
-                    if (userId >= 0) {
-                        getImplForUser(userId).sendInitialBroadcasts();
-                    } else {
-                        Slog.w(TAG, "Incorrect user handle supplied in " + intent);
-                    }
-                } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
-                    for (int i = 0; i < mAppWidgetServices.size(); i++) {
-                        AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i);
-                        service.onConfigurationChanged();
-                    }
-                } else {
-                    int sendingUser = getSendingUserId();
-                    if (sendingUser == UserHandle.USER_ALL) {
-                        for (int i = 0; i < mAppWidgetServices.size(); i++) {
-                            AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i);
-                            service.onBroadcastReceived(intent);
-                        }
-                    } else {
-                        AppWidgetServiceImpl service = mAppWidgetServices.get(sendingUser);
-                        if (service != null) {
-                            service.onBroadcastReceived(intent);
-                        }
-                    }
-                }
-            }
-        };
-    }
 }
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 7a67d63..4315e0d 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -19,21 +19,25 @@
 import android.app.AlarmManager;
 import android.app.AppGlobals;
 import android.app.PendingIntent;
+import android.app.admin.DevicePolicyManagerInternal;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.Intent.FilterComparison;
+import android.content.IntentFilter;
+import android.content.IntentSender;
 import android.content.ServiceConnection;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
@@ -44,16 +48,20 @@
 import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.os.UserManager;
+import android.text.TextUtils;
+import android.util.ArraySet;
 import android.util.AtomicFile;
 import android.util.AttributeSet;
-import android.util.MutableInt;
 import android.util.Pair;
 import android.util.Slog;
-import android.util.SparseArray;
+import android.util.SparseIntArray;
 import android.util.TypedValue;
 import android.util.Xml;
 import android.view.Display;
@@ -61,10 +69,16 @@
 import android.widget.RemoteViews;
 
 import com.android.internal.appwidget.IAppWidgetHost;
+import com.android.internal.appwidget.IAppWidgetService;
+import com.android.internal.os.BackgroundThread;
+import com.android.internal.os.SomeArgs;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.widget.IRemoteViewsAdapterConnection;
 import com.android.internal.widget.IRemoteViewsFactory;
 
+import com.android.server.LocalServices;
+import com.android.server.WidgetBackupProvider;
+import libcore.io.IoUtils;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -79,230 +93,117 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map.Entry;
+import java.util.Map;
 import java.util.Set;
 
-class AppWidgetServiceImpl {
-
-    private static final String KEYGUARD_HOST_PACKAGE = "com.android.keyguard";
-    private static final int KEYGUARD_HOST_ID = 0x4b455947;
+class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBackupProvider {
     private static final String TAG = "AppWidgetServiceImpl";
-    private static final String SETTINGS_FILENAME = "appwidgets.xml";
-    private static final int MIN_UPDATE_PERIOD = 30 * 60 * 1000; // 30 minutes
-    private static final int CURRENT_VERSION = 1; // Bump if the stored widgets need to be upgraded.
-    private static final int WIDGET_STATE_VERSION = 1;  // version of backed-up widget state
 
-    private static boolean DBG = true;
-    private static boolean DEBUG_BACKUP = DBG || true;
+    private static boolean DEBUG = false;
 
-    /*
-     * When identifying a Host or Provider based on the calling process, use the uid field. When
-     * identifying a Host or Provider based on a package manager broadcast, use the package given.
-     */
+    private static final String OLD_KEYGUARD_HOST_PACKAGE = "android";
+    private static final String NEW_KEYGUARD_HOST_PACKAGE = "com.android.keyguard";
+    private static final int KEYGUARD_HOST_ID = 0x4b455947;
 
-    static class Provider {
-        int uid;
-        AppWidgetProviderInfo info;
-        ArrayList<AppWidgetId> instances = new ArrayList<AppWidgetId>();
-        PendingIntent broadcast;
-        boolean zombie; // if we're in safe mode, don't prune this just because nobody references it
+    private static final String STATE_FILENAME = "appwidgets.xml";
 
-        int tag; // for use while saving state (the index)
+    private static final int MIN_UPDATE_PERIOD = DEBUG ? 0 : 30 * 60 * 1000; // 30 minutes
 
-        // is there an instance of this provider hosted by the given app?
-        public boolean isHostedBy(String packageName) {
-            final int N = instances.size();
-            for (int i = 0; i < N; i++) {
-                AppWidgetId id = instances.get(i);
-                if (packageName.equals(id.host.packageName)) {
-                    return true;
-                }
+    private static final int TAG_UNDEFINED = -1;
+
+    private static final int UNKNOWN_UID = -1;
+
+    private static final int LOADED_PROFILE_ID = -1;
+
+    private static final int DISABLED_PROFILE = -1;
+
+    private static final int UNKNOWN_USER_ID = -10;
+
+    // Bump if the stored widgets need to be upgraded.
+    private static final int CURRENT_VERSION = 1;
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+
+            if (DEBUG) {
+                Slog.i(TAG, "Received broadcast: " + action);
             }
-            return false;
-        }
 
-        @Override
-        public String toString() {
-            return "Provider{" + ((info == null) ? "null" : info.provider)
-                    + (zombie ? " Z" : "")
-                    + '}';
-        }
-    }
-
-    static class Host {
-        int uid;
-        int hostId;
-        String packageName;
-        ArrayList<AppWidgetId> instances = new ArrayList<AppWidgetId>();
-        IAppWidgetHost callbacks;
-        boolean zombie; // if we're in safe mode, don't prune this just because nobody references it
-
-        int tag; // for use while saving state (the index)
-
-        boolean uidMatches(int callingUid) {
-            if (UserHandle.getAppId(callingUid) == Process.myUid()) {
-                // For a host that's in the system process, ignore the user id
-                return UserHandle.isSameApp(this.uid, callingUid);
+            if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
+                onConfigurationChanged();
+            } else if (Intent.ACTION_USER_STARTED.equals(action)) {
+                onUserStarted(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+                        UserHandle.USER_NULL));
+            } else if (Intent.ACTION_USER_STOPPED.equals(action)) {
+                onUserStopped(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+                        UserHandle.USER_NULL));
             } else {
-                return this.uid == callingUid;
+                onPackageBroadcastReceived(intent, intent.getIntExtra(
+                        Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL));
             }
         }
+    };
 
-        boolean hostsPackage(String pkg) {
-            final int N = instances.size();
-            for (int i = 0; i < N; i++) {
-                Provider p = instances.get(i).provider;
-                if (p != null && p.info != null && pkg.equals(p.info.provider.getPackageName())) {
-                    return true;
-                }
-            }
-            return false;
-        }
+    // Manages active connections to RemoteViewsServices.
+    private final HashMap<Pair<Integer, FilterComparison>, ServiceConnection>
+            mBoundRemoteViewsServices = new HashMap<>();
 
-        @Override
-        public String toString() {
-            return "Host{" + packageName + ":" + hostId + '}';
-        }
-    }
+    // Manages persistent references to RemoteViewsServices from different App Widgets.
+    private final HashMap<Pair<Integer, FilterComparison>, HashSet<Integer>>
+            mRemoteViewsServicesAppWidgets = new HashMap<>();
 
-    static class AppWidgetId {
-        int appWidgetId;
-        int restoredId;  // tracking & remapping any restored state
-        Provider provider;
-        RemoteViews views;
-        Bundle options;
-        Host host;
+    private final Object mLock = new Object();
 
-        @Override
-        public String toString() {
-            return "AppWidgetId{" + appWidgetId + ':' + host + ':' + provider + '}';
-        }
-    }
+    private final ArrayList<Widget> mWidgets = new ArrayList<>();
+    private final ArrayList<Host> mHosts = new ArrayList<>();
+    private final ArrayList<Provider> mProviders = new ArrayList<>();
 
-    AppWidgetId findRestoredWidgetLocked(int restoredId, Host host, Provider p) {
-        if (DEBUG_BACKUP) {
-            Slog.i(TAG, "Find restored widget: id=" + restoredId
-                    + " host=" + host + " provider=" + p);
-        }
+    private final ArraySet<Pair<Integer, String>> mPackagesWithBindWidgetPermission =
+            new ArraySet<>();
 
-        if (p == null || host == null) {
-            return null;
-        }
+    private final SparseIntArray mLoadedUserIds = new SparseIntArray();
 
-        final int N = mAppWidgetIds.size();
-        for (int i = 0; i < N; i++) {
-            AppWidgetId widget = mAppWidgetIds.get(i);
-            if (widget.restoredId == restoredId
-                    && widget.host.hostId == host.hostId
-                    && widget.host.packageName.equals(host.packageName)
-                    && widget.provider.info.provider.equals(p.info.provider)) {
-                if (DEBUG_BACKUP) {
-                    Slog.i(TAG, "   Found at " + i + " : " + widget);
-                }
-                return widget;
-            }
-        }
-        return null;
-    }
+    private final BackupRestoreController mBackupRestoreController;
 
-    /**
-     * Acts as a proxy between the ServiceConnection and the RemoteViewsAdapterConnection. This
-     * needs to be a static inner class since a reference to the ServiceConnection is held globally
-     * and may lead us to leak AppWidgetService instances (if there were more than one).
-     */
-    static class ServiceConnectionProxy implements ServiceConnection {
-        private final IBinder mConnectionCb;
+    private final Context mContext;
 
-        ServiceConnectionProxy(Pair<Integer, Intent.FilterComparison> key, IBinder connectionCb) {
-            mConnectionCb = connectionCb;
-        }
+    private final IPackageManager mPackageManager;
+    private final AlarmManager mAlarmManager;
+    private final UserManager mUserManager;
 
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            final IRemoteViewsAdapterConnection cb = IRemoteViewsAdapterConnection.Stub
-                    .asInterface(mConnectionCb);
-            try {
-                cb.onServiceConnected(service);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-
-        public void onServiceDisconnected(ComponentName name) {
-            disconnect();
-        }
-
-        public void disconnect() {
-            final IRemoteViewsAdapterConnection cb = IRemoteViewsAdapterConnection.Stub
-                    .asInterface(mConnectionCb);
-            try {
-                cb.onServiceDisconnected();
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    // Manages active connections to RemoteViewsServices
-    private final HashMap<Pair<Integer, FilterComparison>, ServiceConnection> mBoundRemoteViewsServices = new HashMap<Pair<Integer, FilterComparison>, ServiceConnection>();
-    // Manages persistent references to RemoteViewsServices from different App Widgets
-    private final HashMap<FilterComparison, HashSet<Integer>> mRemoteViewsServicesAppWidgets = new HashMap<FilterComparison, HashSet<Integer>>();
-
-    final Context mContext;
-    final IPackageManager mPm;
-    final AlarmManager mAlarmManager;
-    final ArrayList<Provider> mInstalledProviders = new ArrayList<Provider>();
-    final int mUserId;
-    final boolean mHasFeature;
-
-    Locale mLocale;
-    int mNextAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID + 1;
-    final ArrayList<AppWidgetId> mAppWidgetIds = new ArrayList<AppWidgetId>();
-    final ArrayList<Host> mHosts = new ArrayList<Host>();
-    // set of package names
-    final HashSet<String> mPackagesWithBindWidgetPermission = new HashSet<String>();
-    boolean mSafeMode;
-    boolean mStateLoaded;
-    int mMaxWidgetBitmapMemory;
-
-    // Map old (restored) widget IDs to new AppWidgetId instances.  This object is used
-    // as the lock around manipulation of the overall restored-widget state, just as
-    // mAppWidgetIds is used as the lock object around all "live" widget state
-    // manipulations.  Methods that must be called with this lock held are decorated
-    // with the suffix "Lr".
-    //
-    // In cases when both of those locks must be held concurrently, mRestoredWidgetIds
-    // must be acquired *first.*
-    private final SparseArray<AppWidgetId> mRestoredWidgetIds = new SparseArray<AppWidgetId>();
-
-    // We need to make sure to wipe the pre-restore widget state only once for
-    // a given package.  Keep track of what we've done so far here; the list is
-    // cleared at the start of every system restore pass, but preserved through
-    // any install-time restore operations.
-    HashSet<String> mPrunedApps = new HashSet<String>();
+    private final SecurityPolicy mSecurityPolicy;
 
     private final Handler mSaveStateHandler;
+    private final Handler mCallbackHandler;
 
-    // These are for debugging only -- widgets are going missing in some rare instances
-    ArrayList<Provider> mDeletedProviders = new ArrayList<Provider>();
-    ArrayList<Host> mDeletedHosts = new ArrayList<Host>();
+    private Locale mLocale;
 
-    AppWidgetServiceImpl(Context context, int userId, Handler saveStateHandler) {
+    private final SparseIntArray mNextAppWidgetIds = new SparseIntArray();
+
+    private boolean mSafeMode;
+    private int mMaxWidgetBitmapMemory;
+
+    AppWidgetServiceImpl(Context context) {
         mContext = context;
-        mPm = AppGlobals.getPackageManager();
+        mPackageManager = AppGlobals.getPackageManager();
         mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
-        mUserId = userId;
-        mSaveStateHandler = saveStateHandler;
-        mHasFeature = context.getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_APP_WIDGETS);
+        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        mSaveStateHandler = BackgroundThread.getHandler();
+        mCallbackHandler = new CallbackHandler(mContext.getMainLooper());
+        mBackupRestoreController = new BackupRestoreController();
+        mSecurityPolicy = new SecurityPolicy();
         computeMaximumWidgetBitmapMemory();
+        registerBroadcastReceiver();
     }
 
-    void computeMaximumWidgetBitmapMemory() {
+    private void computeMaximumWidgetBitmapMemory() {
         WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
         Display display = wm.getDefaultDisplay();
         Point size = new Point();
@@ -312,51 +213,99 @@
         mMaxWidgetBitmapMemory = 6 * size.x * size.y;
     }
 
-    public void systemReady(boolean safeMode) {
+    private void registerBroadcastReceiver() {
+        // Register for configuration changes so we can update the names
+        // of the widgets when the locale changes.
+        IntentFilter configFilter = new IntentFilter();
+        configFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
+        mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
+                configFilter, null, null);
+
+        // Register for broadcasts about package install, etc., so we can
+        // update the provider list.
+        IntentFilter packageFilter = new IntentFilter();
+        packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        packageFilter.addDataScheme("package");
+        mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
+                packageFilter, null, null);
+
+        // Register for events related to sdcard installation.
+        IntentFilter sdFilter = new IntentFilter();
+        sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
+        sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
+        mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
+                sdFilter, null, null);
+
+        IntentFilter userFilter = new IntentFilter();
+        userFilter.addAction(Intent.ACTION_USER_STARTED);
+        userFilter.addAction(Intent.ACTION_USER_STOPPED);
+        mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
+                userFilter, null, null);
+    }
+
+    public void setSafeMode(boolean safeMode) {
         mSafeMode = safeMode;
+    }
 
-        synchronized (mAppWidgetIds) {
-            ensureStateLoadedLocked();
+    private void onConfigurationChanged() {
+        if (DEBUG) {
+            Slog.i(TAG, "onConfigurationChanged()");
         }
-    }
 
-    private void log(String msg) {
-        Slog.i(TAG, "u=" + mUserId + ": " + msg);
-    }
-
-    void onConfigurationChanged() {
-        if (DBG) log("Got onConfigurationChanged()");
         Locale revised = Locale.getDefault();
-        if (revised == null || mLocale == null || !(revised.equals(mLocale))) {
+        if (revised == null || mLocale == null || !revised.equals(mLocale)) {
             mLocale = revised;
 
-            synchronized (mAppWidgetIds) {
-                ensureStateLoadedLocked();
+            synchronized (mLock) {
+                SparseIntArray changedGroups = null;
+
                 // Note: updateProvidersForPackageLocked() may remove providers, so we must copy the
                 // list of installed providers and skip providers that we don't need to update.
                 // Also note that remove the provider does not clear the Provider component data.
-                ArrayList<Provider> installedProviders =
-                        new ArrayList<Provider>(mInstalledProviders);
-                HashSet<ComponentName> removedProviders = new HashSet<ComponentName>();
+                ArrayList<Provider> installedProviders = new ArrayList<>(mProviders);
+                HashSet<ProviderId> removedProviders = new HashSet<>();
+
                 int N = installedProviders.size();
                 for (int i = N - 1; i >= 0; i--) {
-                    Provider p = installedProviders.get(i);
-                    ComponentName cn = p.info.provider;
-                    if (!removedProviders.contains(cn)) {
-                        updateProvidersForPackageLocked(cn.getPackageName(), removedProviders);
+                    Provider provider = installedProviders.get(i);
+
+                    ensureGroupStateLoadedLocked(provider.getUserId());
+
+                    if (!removedProviders.contains(provider.id)) {
+                        final boolean changed = updateProvidersForPackageLocked(
+                                provider.id.componentName.getPackageName(),
+                                provider.getUserId(), removedProviders);
+
+                        if (changed) {
+                            if (changedGroups == null) {
+                                changedGroups = new SparseIntArray();
+                            }
+                            final int groupId = mSecurityPolicy.getGroupParent(
+                                    provider.getUserId());
+                            changedGroups.put(groupId, groupId);
+                        }
                     }
                 }
-                saveStateAsync();
+
+                if (changedGroups != null) {
+                    final int groupCount = changedGroups.size();
+                    for (int i = 0; i < groupCount; i++) {
+                        final int groupId = changedGroups.get(i);
+                        saveGroupStateAsync(groupId);
+                    }
+                }
             }
         }
     }
 
-    void onBroadcastReceived(Intent intent) {
-        if (DBG) log("onBroadcast " + intent);
+    private void onPackageBroadcastReceived(Intent intent, int userId) {
         final String action = intent.getAction();
         boolean added = false;
         boolean changed = false;
-        boolean providersModified = false;
+        boolean componentsModified = false;
+
         String pkgList[] = null;
         if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
             pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
@@ -380,555 +329,1177 @@
         if (pkgList == null || pkgList.length == 0) {
             return;
         }
-        if (added || changed) {
-            synchronized (mAppWidgetIds) {
-                ensureStateLoadedLocked();
-                Bundle extras = intent.getExtras();
-                if (changed
-                        || (extras != null && extras.getBoolean(Intent.EXTRA_REPLACING, false))) {
-                    for (String pkgName : pkgList) {
-                        // The package was just upgraded
-                        providersModified |= updateProvidersForPackageLocked(pkgName, null);
-                    }
-                } else {
-                    // The package was just added.  Fix up the providers...
-                    for (String pkgName : pkgList) {
-                        providersModified |= addProvidersForPackageLocked(pkgName);
-                    }
-                    // ...and see if these are hosts we've been awaiting
-                    for (String pkg : pkgList) {
-                        try {
-                            int uid = getUidForPackage(pkg);
-                            resolveHostUidLocked(pkg, uid);
-                        } catch (NameNotFoundException e) {
-                            // shouldn't happen; we just installed it!
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            Bundle extras = intent.getExtras();
+
+            if (added || changed) {
+                final boolean newPackageAdded = added && (extras == null
+                        || !extras.getBoolean(Intent.EXTRA_REPLACING, false));
+
+                for (String pkgName : pkgList) {
+                    // Fix up the providers - add/remove/update.
+                    componentsModified |= updateProvidersForPackageLocked(pkgName, userId, null);
+
+                    // ... and see if these are hosts we've been awaiting.
+                    // NOTE: We are backing up and restoring only the owner.
+                    if (newPackageAdded && userId == UserHandle.USER_OWNER) {
+                        final int uid = getUidForPackage(pkgName, userId);
+                        if (uid >= 0 ) {
+                            resolveHostUidLocked(pkgName, uid);
                         }
                     }
                 }
-                saveStateAsync();
-            }
-        } else {
-            Bundle extras = intent.getExtras();
-            if (extras != null && extras.getBoolean(Intent.EXTRA_REPLACING, false)) {
-                // The package is being updated. We'll receive a PACKAGE_ADDED shortly.
             } else {
-                synchronized (mAppWidgetIds) {
-                    ensureStateLoadedLocked();
+                // If the package is being updated, we'll receive a PACKAGE_ADDED
+                // shortly, otherwise it is removed permanently.
+                final boolean packageRemovedPermanently = (extras == null
+                        || !extras.getBoolean(Intent.EXTRA_REPLACING, false));
+
+                if (packageRemovedPermanently) {
                     for (String pkgName : pkgList) {
-                        providersModified |= removeProvidersForPackageLocked(pkgName);
-                        saveStateAsync();
+                        componentsModified |= removeHostsAndProvidersForPackageLocked(
+                                pkgName, userId);
                     }
                 }
             }
-        }
 
-        if (providersModified) {
-            // If the set of providers has been modified, notify each active AppWidgetHost
-            synchronized (mAppWidgetIds) {
-                ensureStateLoadedLocked();
-                notifyHostsForProvidersChangedLocked();
+            if (componentsModified) {
+                saveGroupStateAsync(userId);
+
+                // If the set of providers has been modified, notify each active AppWidgetHost
+                scheduleNotifyHostsForProvidersChangedLocked();
             }
         }
     }
 
-    void resolveHostUidLocked(String pkg, int uid) {
+    private void resolveHostUidLocked(String pkg, int uid) {
         final int N = mHosts.size();
         for (int i = 0; i < N; i++) {
-            Host h = mHosts.get(i);
-            if (h.uid == -1 && pkg.equals(h.packageName)) {
-                if (DEBUG_BACKUP) {
-                    Slog.i(TAG, "host " + pkg + ":" + h.hostId + " resolved to uid " + uid);
+            Host host = mHosts.get(i);
+            if (host.id.uid == UNKNOWN_UID && pkg.equals(host.id.packageName)) {
+                if (DEBUG) {
+                    Slog.i(TAG, "host " + host.id + " resolved to uid " + uid);
                 }
-                h.uid = uid;
+                host.id = new HostId(uid, host.id.hostId, host.id.packageName);
+                return;
             }
         }
     }
 
-    private void dumpProvider(Provider p, int index, PrintWriter pw) {
-        AppWidgetProviderInfo info = p.info;
-        pw.print("  ["); pw.print(index); pw.print("] provider ");
-                pw.print(info.provider.flattenToShortString());
-                pw.println(':');
-        pw.print("    min=("); pw.print(info.minWidth);
-                pw.print("x"); pw.print(info.minHeight);
-        pw.print(")   minResize=("); pw.print(info.minResizeWidth);
-                pw.print("x"); pw.print(info.minResizeHeight);
-                pw.print(") updatePeriodMillis=");
-                pw.print(info.updatePeriodMillis);
-                pw.print(" resizeMode=");
-                pw.print(info.resizeMode);
-                pw.print(info.widgetCategory);
-                pw.print(" autoAdvanceViewId=");
-                pw.print(info.autoAdvanceViewId);
-                pw.print(" initialLayout=#");
-                pw.print(Integer.toHexString(info.initialLayout));
-                pw.print(" uid="); pw.print(p.uid);
-                pw.print(" zombie="); pw.println(p.zombie);
-    }
+    private void ensureGroupStateLoadedLocked(int userId) {
+        final int[] profileIds = mSecurityPolicy.getEnabledGroupProfileIds(userId);
 
-    private void dumpHost(Host host, int index, PrintWriter pw) {
-        pw.print("  ["); pw.print(index); pw.print("] hostId=");
-                pw.print(host.hostId); pw.print(' ');
-                pw.print(host.packageName); pw.print('/');
-        pw.print(host.uid); pw.println(':');
-        pw.print("    callbacks="); pw.println(host.callbacks);
-        pw.print("    instances.size="); pw.print(host.instances.size());
-                pw.print(" zombie="); pw.println(host.zombie);
-    }
+        // Careful lad, we may have already loaded the state for some
+        // group members, so check before loading and read only the
+        // state for the new member(s).
+        int newMemberCount = 0;
+        final int profileIdCount = profileIds.length;
+        for (int i = 0; i < profileIdCount; i++) {
+            final int profileId = profileIds[i];
+            if (mLoadedUserIds.indexOfKey(profileId) >= 0) {
+                profileIds[i] = LOADED_PROFILE_ID;
+            } else {
+                newMemberCount++;
+            }
+        }
 
-    private void dumpAppWidgetId(AppWidgetId id, int index, PrintWriter pw) {
-        pw.print("  ["); pw.print(index); pw.print("] id=");
-                pw.println(id.appWidgetId);
-        pw.print("    hostId=");
-                pw.print(id.host.hostId); pw.print(' ');
-                pw.print(id.host.packageName); pw.print('/');
-                pw.println(id.host.uid);
-        if (id.provider != null) {
-            pw.print("    provider=");
-                    pw.println(id.provider.info.provider.flattenToShortString());
-        }
-        if (id.host != null) {
-            pw.print("    host.callbacks="); pw.println(id.host.callbacks);
-        }
-        if (id.views != null) {
-            pw.print("    views="); pw.println(id.views);
-        }
-    }
-
-    void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
-                != PackageManager.PERMISSION_GRANTED) {
-            pw.println("Permission Denial: can't dump from from pid="
-                    + Binder.getCallingPid()
-                    + ", uid=" + Binder.getCallingUid());
+        if (newMemberCount <= 0) {
             return;
         }
 
-        synchronized (mAppWidgetIds) {
-            int N = mInstalledProviders.size();
+        int newMemberIndex = 0;
+        final int[] newProfileIds = new int[newMemberCount];
+        for (int i = 0; i < profileIdCount; i++) {
+            final int profileId = profileIds[i];
+            if (profileId != LOADED_PROFILE_ID) {
+                mLoadedUserIds.put(profileId, profileId);
+                newProfileIds[newMemberIndex] = profileId;
+                newMemberIndex++;
+            }
+        }
+
+        loadGroupWidgetProvidersLocked(newProfileIds);
+        loadGroupStateLocked(newProfileIds);
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Permission Denial: can't dump from from pid="
+                    + Binder.getCallingPid()
+                    + ", uid=" + Binder.getCallingUid());
+        }
+
+        synchronized (mLock) {
+            int N = mProviders.size();
             pw.println("Providers:");
-            for (int i=0; i<N; i++) {
-                dumpProvider(mInstalledProviders.get(i), i, pw);
+            for (int i = 0; i < N; i++) {
+                dumpProvider(mProviders.get(i), i, pw);
             }
 
-            N = mAppWidgetIds.size();
+            N = mWidgets.size();
             pw.println(" ");
-            pw.println("AppWidgetIds:");
-            for (int i=0; i<N; i++) {
-                dumpAppWidgetId(mAppWidgetIds.get(i), i, pw);
+            pw.println("Widgets:");
+            for (int i = 0; i < N; i++) {
+                dumpWidget(mWidgets.get(i), i, pw);
             }
 
             N = mHosts.size();
             pw.println(" ");
             pw.println("Hosts:");
-            for (int i=0; i<N; i++) {
+            for (int i = 0; i < N; i++) {
                 dumpHost(mHosts.get(i), i, pw);
             }
 
-            N = mDeletedProviders.size();
-            pw.println(" ");
-            pw.println("Deleted Providers:");
-            for (int i=0; i<N; i++) {
-                dumpProvider(mDeletedProviders.get(i), i, pw);
-            }
 
-            N = mDeletedHosts.size();
+            N = mPackagesWithBindWidgetPermission.size();
             pw.println(" ");
-            pw.println("Deleted Hosts:");
-            for (int i=0; i<N; i++) {
-                dumpHost(mDeletedHosts.get(i), i, pw);
+            pw.println("Grants:");
+            for (int i = 0; i < N; i++) {
+                Pair<Integer, String> grant = mPackagesWithBindWidgetPermission.valueAt(i);
+                dumpGrant(grant, i, pw);
             }
         }
     }
 
-    private void ensureStateLoadedLocked() {
-        if (!mStateLoaded) {
-            if (!mHasFeature) {
-                return;
+    @Override
+    public int[] startListening(IAppWidgetHost callbacks, String callingPackage,
+            int hostId, List<RemoteViews> updatedViews) {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (DEBUG) {
+            Slog.i(TAG, "startListening() " + userId);
+        }
+
+        // Make sure the package runs under the caller uid.
+        mSecurityPolicy.enforceCallFromPackage(callingPackage);
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            // NOTE: The lookup is enforcing security across users by making
+            // sure the caller can only access hosts it owns.
+            HostId id = new HostId(Binder.getCallingUid(), hostId, callingPackage);
+            Host host = lookupOrAddHostLocked(id);
+
+            host.callbacks = callbacks;
+
+            updatedViews.clear();
+
+            ArrayList<Widget> instances = host.widgets;
+            int N = instances.size();
+            int[] updatedIds = new int[N];
+            for (int i = 0; i < N; i++) {
+                Widget widget = instances.get(i);
+                updatedIds[i] = widget.appWidgetId;
+                updatedViews.add(cloneIfLocalBinder(widget.views));
             }
-            loadWidgetProviderListLocked();
-            loadStateLocked();
-            mStateLoaded = true;
+
+            return updatedIds;
         }
     }
 
-    public int allocateAppWidgetId(String packageName, int hostId) {
-        int callingUid = enforceSystemOrCallingUid(packageName);
-        synchronized (mAppWidgetIds) {
-            if (!mHasFeature) {
-                return -1;
+    @Override
+    public void stopListening(String callingPackage, int hostId) {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (DEBUG) {
+            Slog.i(TAG, "stopListening() " + userId);
+        }
+
+        // Make sure the package runs under the caller uid.
+        mSecurityPolicy.enforceCallFromPackage(callingPackage);
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            // NOTE: The lookup is enforcing security across users by making
+            // sure the caller can only access hosts it owns.
+            HostId id = new HostId(Binder.getCallingUid(), hostId, callingPackage);
+            Host host = lookupHostLocked(id);
+
+            if (host != null) {
+                host.callbacks = null;
+                pruneHostLocked(host);
             }
-            ensureStateLoadedLocked();
-            int appWidgetId = mNextAppWidgetId++;
+        }
+    }
 
-            Host host = lookupOrAddHostLocked(callingUid, packageName, hostId);
+    @Override
+    public int allocateAppWidgetId(String callingPackage, int hostId) {
+        final int userId = UserHandle.getCallingUserId();
 
-            AppWidgetId id = new AppWidgetId();
-            id.appWidgetId = appWidgetId;
-            id.host = host;
+        if (DEBUG) {
+            Slog.i(TAG, "allocateAppWidgetId() " + userId);
+        }
 
-            host.instances.add(id);
-            mAppWidgetIds.add(id);
+        // Make sure the package runs under the caller uid.
+        mSecurityPolicy.enforceCallFromPackage(callingPackage);
 
-            saveStateAsync();
-            if (DBG) log("Allocating AppWidgetId for " + packageName + " host=" + hostId
-                    + " id=" + appWidgetId);
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            if (mNextAppWidgetIds.indexOfKey(userId) < 0) {
+                mNextAppWidgetIds.put(userId, AppWidgetManager.INVALID_APPWIDGET_ID + 1);
+            }
+
+            final int appWidgetId = incrementAndGetAppWidgetIdLocked(userId);
+
+            // NOTE: The lookup is enforcing security across users by making
+            // sure the caller can only access hosts it owns.
+            HostId id = new HostId(Binder.getCallingUid(), hostId, callingPackage);
+            Host host = lookupOrAddHostLocked(id);
+
+            Widget widget = new Widget();
+            widget.appWidgetId = appWidgetId;
+            widget.host = host;
+
+            host.widgets.add(widget);
+            mWidgets.add(widget);
+
+            saveGroupStateAsync(userId);
+
+            if (DEBUG) {
+                Slog.i(TAG, "Allocated widget id " + appWidgetId
+                        + " for host " + host.id);
+            }
+
             return appWidgetId;
         }
     }
 
-    public void deleteAppWidgetId(int appWidgetId) {
-        synchronized (mAppWidgetIds) {
-            if (!mHasFeature) {
+    @Override
+    public void deleteAppWidgetId(String callingPackage, int appWidgetId) {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (DEBUG) {
+            Slog.i(TAG, "deleteAppWidgetId() " + userId);
+        }
+
+        // Make sure the package runs under the caller uid.
+        mSecurityPolicy.enforceCallFromPackage(callingPackage);
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            // NOTE: The lookup is enforcing security across users by making
+            // sure the caller can only access widgets it hosts or provides.
+            Widget widget = lookupWidgetLocked(appWidgetId,
+                    Binder.getCallingUid(), callingPackage);
+
+            if (widget == null) {
                 return;
             }
-            ensureStateLoadedLocked();
-            AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
-            if (id != null) {
-                deleteAppWidgetLocked(id);
-                saveStateAsync();
+
+            deleteAppWidgetLocked(widget);
+
+            saveGroupStateAsync(userId);
+
+            if (DEBUG) {
+                Slog.i(TAG, "Deleted widget id " + appWidgetId
+                        + " for host " + widget.host.id);
             }
         }
     }
 
-    public void deleteHost(int hostId) {
-        synchronized (mAppWidgetIds) {
-            if (!mHasFeature) {
-                return;
-            }
-            ensureStateLoadedLocked();
-            int callingUid = Binder.getCallingUid();
-            Host host = lookupHostLocked(callingUid, hostId);
-            if (host != null) {
-                deleteHostLocked(host);
-                saveStateAsync();
-            }
+    @Override
+    public boolean hasBindAppWidgetPermission(String packageName, int grantId) {
+        if (DEBUG) {
+            Slog.i(TAG, "hasBindAppWidgetPermission() " + UserHandle.getCallingUserId());
         }
-    }
 
-    public void deleteAllHosts() {
-        synchronized (mAppWidgetIds) {
-            if (!mHasFeature) {
-                return;
-            }
-            ensureStateLoadedLocked();
-            int callingUid = Binder.getCallingUid();
-            final int N = mHosts.size();
-            boolean changed = false;
-            for (int i = N - 1; i >= 0; i--) {
-                Host host = mHosts.get(i);
-                if (host.uidMatches(callingUid)) {
-                    deleteHostLocked(host);
-                    changed = true;
-                }
-            }
-            if (changed) {
-                saveStateAsync();
-            }
-        }
-    }
+        // A special permission is required for managing white listing.
+        mSecurityPolicy.enforceModifyAppWidgetBindPermissions(packageName);
 
-    void deleteHostLocked(Host host) {
-        if (DBG) log("Deleting host " + host);
-        final int N = host.instances.size();
-        for (int i = N - 1; i >= 0; i--) {
-            AppWidgetId id = host.instances.get(i);
-            deleteAppWidgetLocked(id);
-        }
-        host.instances.clear();
-        mHosts.remove(host);
-        mDeletedHosts.add(host);
-        // it's gone or going away, abruptly drop the callback connection
-        host.callbacks = null;
-    }
+        synchronized (mLock) {
+            // The grants are stored in user state wich gets the grant.
+            ensureGroupStateLoadedLocked(grantId);
 
-    void deleteAppWidgetLocked(AppWidgetId id) {
-        // We first unbind all services that are bound to this id
-        unbindAppWidgetRemoteViewsServicesLocked(id);
-
-        Host host = id.host;
-        host.instances.remove(id);
-        pruneHostLocked(host);
-
-        mAppWidgetIds.remove(id);
-
-        Provider p = id.provider;
-        if (p != null) {
-            p.instances.remove(id);
-            if (!p.zombie) {
-                // send the broacast saying that this appWidgetId has been deleted
-                Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_DELETED);
-                intent.setComponent(p.info.provider);
-                intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id.appWidgetId);
-                mContext.sendBroadcastAsUser(intent, new UserHandle(mUserId));
-                if (p.instances.size() == 0) {
-                    // cancel the future updates
-                    cancelBroadcasts(p);
-
-                    // send the broacast saying that the provider is not in use any more
-                    intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_DISABLED);
-                    intent.setComponent(p.info.provider);
-                    mContext.sendBroadcastAsUser(intent, new UserHandle(mUserId));
-                }
-            }
-        }
-    }
-
-    void cancelBroadcasts(Provider p) {
-        if (DBG) log("cancelBroadcasts for " + p);
-        if (p.broadcast != null) {
-            mAlarmManager.cancel(p.broadcast);
-            long token = Binder.clearCallingIdentity();
-            try {
-                p.broadcast.cancel();
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-            p.broadcast = null;
-        }
-    }
-
-    private void bindAppWidgetIdImpl(int appWidgetId, ComponentName provider, Bundle options) {
-        if (DBG) log("bindAppWidgetIdImpl appwid=" + appWidgetId
-                + " provider=" + provider);
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            synchronized (mAppWidgetIds) {
-                if (!mHasFeature) {
-                    return;
-                }
-                options = cloneIfLocalBinder(options);
-                ensureStateLoadedLocked();
-                AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
-                if (id == null) {
-                    throw new IllegalArgumentException("bad appWidgetId");
-                }
-                if (id.provider != null) {
-                    throw new IllegalArgumentException("appWidgetId " + appWidgetId
-                            + " already bound to " + id.provider.info.provider);
-                }
-                Provider p = lookupProviderLocked(provider);
-                if (p == null) {
-                    throw new IllegalArgumentException("not a appwidget provider: " + provider);
-                }
-                if (p.zombie) {
-                    throw new IllegalArgumentException("can't bind to a 3rd party provider in"
-                            + " safe mode: " + provider);
-                }
-
-                id.provider = p;
-                if (options == null) {
-                    options = new Bundle();
-                }
-                id.options = options;
-
-                // We need to provide a default value for the widget category if it is not specified
-                if (!options.containsKey(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY)) {
-                    options.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
-                            AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN);
-                }
-
-                p.instances.add(id);
-                int instancesSize = p.instances.size();
-                if (instancesSize == 1) {
-                    // tell the provider that it's ready
-                    sendEnableIntentLocked(p);
-                }
-
-                // send an update now -- We need this update now, and just for this appWidgetId.
-                // It's less critical when the next one happens, so when we schedule the next one,
-                // we add updatePeriodMillis to its start time. That time will have some slop,
-                // but that's okay.
-                sendUpdateIntentLocked(p, new int[] { appWidgetId });
-
-                // schedule the future updates
-                registerForBroadcastsLocked(p, getAppWidgetIds(p));
-                saveStateAsync();
-            }
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BIND_APPWIDGET,
-            "bindAppWidgetId appWidgetId=" + appWidgetId + " provider=" + provider);
-        bindAppWidgetIdImpl(appWidgetId, provider, options);
-    }
-
-    public boolean bindAppWidgetIdIfAllowed(
-            String packageName, int appWidgetId, ComponentName provider, Bundle options) {
-        if (!mHasFeature) {
-            return false;
-        }
-        try {
-            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BIND_APPWIDGET, null);
-        } catch (SecurityException se) {
-            if (!callerHasBindAppWidgetPermission(packageName)) {
+            final int packageUid = getUidForPackage(packageName, grantId);
+            if (packageUid < 0) {
                 return false;
             }
+
+            Pair<Integer, String> packageId = Pair.create(grantId, packageName);
+            return mPackagesWithBindWidgetPermission.contains(packageId);
         }
-        bindAppWidgetIdImpl(appWidgetId, provider, options);
+    }
+
+    @Override
+    public void setBindAppWidgetPermission(String packageName, int grantId,
+            boolean grantPermission) {
+        if (DEBUG) {
+            Slog.i(TAG, "setBindAppWidgetPermission() " + UserHandle.getCallingUserId());
+        }
+
+        // A special permission is required for managing white listing.
+        mSecurityPolicy.enforceModifyAppWidgetBindPermissions(packageName);
+
+        synchronized (mLock) {
+            // The grants are stored in user state wich gets the grant.
+            ensureGroupStateLoadedLocked(grantId);
+
+            final int packageUid = getUidForPackage(packageName, grantId);
+            if (packageUid < 0) {
+                return;
+            }
+
+            Pair<Integer, String> packageId = Pair.create(grantId, packageName);
+            if (grantPermission) {
+                mPackagesWithBindWidgetPermission.add(packageId);
+            } else {
+                mPackagesWithBindWidgetPermission.remove(packageId);
+            }
+
+            saveGroupStateAsync(grantId);
+        }
+    }
+
+    @Override
+    public IntentSender createAppWidgetConfigIntentSender(String callingPackage, Intent intent) {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (DEBUG) {
+            Slog.i(TAG, "createAppWidgetConfigIntentSender() " + userId);
+        }
+
+        // Make sure the package runs under the caller uid.
+        mSecurityPolicy.enforceCallFromPackage(callingPackage);
+
+        // The only allowed action is the one to start the configure activity.
+        if (!AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
+            throw new IllegalArgumentException("Only allowed action is "
+                    + AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
+        }
+
+        // Verify that widget id is provided.
+        final int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
+                AppWidgetManager.INVALID_APPWIDGET_ID);
+        if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
+            throw new IllegalArgumentException("Widget id required");
+        }
+
+        // Make sure a component name is provided.
+        ComponentName component = intent.getComponent();
+        if (component == null) {
+            throw new IllegalArgumentException("Component name required");
+        }
+
+        // Verify the user handle.
+        UserHandle userHandle = intent.getParcelableExtra(
+                AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);
+        if (userHandle != null) {
+            // Remove the profile extra as the receiver already runs under this
+            // user and this information is of no use to this receiver.
+            intent.removeExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);
+
+            // If the user handle is not the caller, check if it is an enabled
+            // profile for which the package is white-listed.
+            final int profileId = userHandle.getIdentifier();
+            if (profileId != userId) {
+                // Make sure the passed user handle is a profile in the group.
+                final int[] profileIds = mSecurityPolicy.resolveCallerEnabledGroupProfiles(
+                        new int[]{profileId});
+                if (profileIds.length <= 0) {
+                    // The profile is not in the group or not enabled, done.
+                    return null;
+                }
+
+                // Make sure the provider is white-listed.
+                if (!mSecurityPolicy.isProviderInCallerOrInProfileAndWhitelListed(
+                        component.getPackageName(), profileId)) {
+                    throw new IllegalArgumentException("Cannot access provider "
+                            + component + " in user " + profileIds);
+                }
+            }
+        } else {
+            // If a profile is not specified use the caller user id.
+            userHandle = new UserHandle(userId);
+        }
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            // NOTE: The lookup is enforcing security across users by making
+            // sure the caller can only access widgets it hosts or provides.
+            Widget widget = lookupWidgetLocked(appWidgetId,
+                    Binder.getCallingUid(), callingPackage);
+
+            if (widget == null) {
+                throw new IllegalArgumentException("Bad widget id " + appWidgetId);
+            }
+
+            Provider provider = widget.provider;
+            if (provider == null) {
+                throw new IllegalArgumentException("Widget not bound " + appWidgetId);
+            }
+
+            // Make sure the component refers to the provider config activity.
+            if (!component.equals(provider.info.configure)
+                    || !provider.info.getProfile().equals(userHandle)) {
+                throw new IllegalArgumentException("No component" + component
+                        + " for user " + userHandle.getIdentifier());
+            }
+
+            // All right, create the sender.
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                return PendingIntent.getActivityAsUser(
+                        mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT
+                                | PendingIntent.FLAG_CANCEL_CURRENT, null, userHandle)
+                        .getIntentSender();
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+    }
+
+    @Override
+    public boolean bindAppWidgetId(String callingPackage, int appWidgetId,
+            int providerProfileId, ComponentName providerComponent, Bundle options) {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (DEBUG) {
+            Slog.i(TAG, "bindAppWidgetId() " + userId);
+        }
+
+        // Make sure the package runs under the caller uid.
+        mSecurityPolicy.enforceCallFromPackage(callingPackage);
+
+        // Check that if a cross-profile binding is attempted, it is allowed.
+        final int[] profileIds = mSecurityPolicy.resolveCallerEnabledGroupProfiles(
+                new int[] {providerProfileId});
+        if (profileIds.length <= 0) {
+            return false;
+        }
+
+        // If the provider is not under the calling user, make sure this
+        // provider is white listed for access from the parent.
+        if (!mSecurityPolicy.isProviderInCallerOrInProfileAndWhitelListed(
+                providerComponent.getPackageName(), providerProfileId)) {
+            return false;
+        }
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            // A special permission or white listing is required to bind widgets.
+            if (!mSecurityPolicy.hasCallerBindPermissionOrBindWhiteListedLocked(
+                    callingPackage)) {
+                return false;
+            }
+
+            // NOTE: The lookup is enforcing security across users by making
+            // sure the caller can only access widgets it hosts or provides.
+            Widget widget = lookupWidgetLocked(appWidgetId,
+                    Binder.getCallingUid(), callingPackage);
+
+            if (widget == null) {
+                Slog.e(TAG, "Bad widget id " + appWidgetId);
+                return false;
+            }
+
+            if (widget.provider != null) {
+                Slog.e(TAG, "Widget id " + appWidgetId
+                        + " already bound to: " + widget.provider.id);
+                return false;
+            }
+
+            final int providerUid = getUidForPackage(providerComponent.getPackageName(),
+                    providerProfileId);
+            if (providerUid < 0) {
+                Slog.e(TAG, "Package " + providerComponent.getPackageName() + " not installed "
+                        + " for profile " + providerProfileId);
+                return false;
+            }
+
+            // NOTE: The lookup is enforcing security across users by making
+            // sure the provider is in the already vetted user profile.
+            ProviderId providerId = new ProviderId(providerUid, providerComponent);
+            Provider provider = lookupProviderLocked(providerId);
+
+            if (provider == null) {
+                Slog.e(TAG, "No widget provider " + providerComponent + " for profile "
+                        + providerProfileId);
+                return false;
+            }
+
+            if (provider.zombie) {
+                Slog.e(TAG, "Can't bind to a 3rd party provider in"
+                        + " safe mode " + provider);
+                return false;
+            }
+
+            widget.provider = provider;
+            widget.options = (options != null) ? cloneIfLocalBinder(options) : new Bundle();
+
+            // We need to provide a default value for the widget category if it is not specified
+            if (!widget.options.containsKey(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY)) {
+                widget.options.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
+                        AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN);
+            }
+
+            provider.widgets.add(widget);
+
+            final int widgetCount = provider.widgets.size();
+            if (widgetCount == 1) {
+                // Tell the provider that it's ready.
+                sendEnableIntentLocked(provider);
+            }
+
+            // Send an update now -- We need this update now, and just for this appWidgetId.
+            // It's less critical when the next one happens, so when we schedule the next one,
+            // we add updatePeriodMillis to its start time. That time will have some slop,
+            // but that's okay.
+            sendUpdateIntentLocked(provider, new int[] {appWidgetId});
+
+            // Schedule the future updates.
+            registerForBroadcastsLocked(provider, getWidgetIds(provider.widgets));
+
+            saveGroupStateAsync(userId);
+
+            if (DEBUG) {
+                Slog.i(TAG, "Bound widget " + appWidgetId + " to provider " + provider.id);
+            }
+        }
+
         return true;
     }
 
-    private boolean callerHasBindAppWidgetPermission(String packageName) {
-        int callingUid = Binder.getCallingUid();
-        try {
-            if (!UserHandle.isSameApp(callingUid, getUidForPackage(packageName))) {
-                return false;
-            }
-        } catch (Exception e) {
-            return false;
+    @Override
+    public int[] getAppWidgetIds(ComponentName componentName) {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (DEBUG) {
+            Slog.i(TAG, "getAppWidgetIds() " + userId);
         }
-        synchronized (mAppWidgetIds) {
-            ensureStateLoadedLocked();
-            return mPackagesWithBindWidgetPermission.contains(packageName);
+
+        // Make sure the package runs under the caller uid.
+        mSecurityPolicy.enforceCallFromPackage(componentName.getPackageName());
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            // NOTE: The lookup is enforcing security across users by making
+            // sure the caller can access only its providers.
+            ProviderId providerId = new ProviderId(Binder.getCallingUid(), componentName);
+            Provider provider = lookupProviderLocked(providerId);
+
+            if (provider != null) {
+                return getWidgetIds(provider.widgets);
+            }
+
+            return new int[0];
         }
     }
 
-    public boolean hasBindAppWidgetPermission(String packageName) {
-        if (!mHasFeature) {
-            return false;
-        }
-        mContext.enforceCallingPermission(
-                android.Manifest.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS,
-                "hasBindAppWidgetPermission packageName=" + packageName);
+    @Override
+    public int[] getAppWidgetIdsForHost(String callingPackage, int hostId) {
+        final int userId = UserHandle.getCallingUserId();
 
-        synchronized (mAppWidgetIds) {
-            ensureStateLoadedLocked();
-            return mPackagesWithBindWidgetPermission.contains(packageName);
+        if (DEBUG) {
+            Slog.i(TAG, "getAppWidgetIdsForHost() " + userId);
+        }
+
+        // Make sure the package runs under the caller uid.
+        mSecurityPolicy.enforceCallFromPackage(callingPackage);
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            // NOTE: The lookup is enforcing security across users by making
+            // sure the caller can only access its hosts.
+            HostId id = new HostId(Binder.getCallingUid(), hostId, callingPackage);
+            Host host = lookupHostLocked(id);
+
+            if (host != null) {
+                return getWidgetIds(host.widgets);
+            }
+
+            return new int[0];
         }
     }
 
-    public void setBindAppWidgetPermission(String packageName, boolean permission) {
-        if (!mHasFeature) {
-            return;
+    @Override
+    public void bindRemoteViewsService(String callingPackage, int appWidgetId,
+            Intent intent, IBinder callbacks) {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (DEBUG) {
+            Slog.i(TAG, "bindRemoteViewsService() " + userId);
         }
-        mContext.enforceCallingPermission(
-                android.Manifest.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS,
-                "setBindAppWidgetPermission packageName=" + packageName);
 
-        synchronized (mAppWidgetIds) {
-            ensureStateLoadedLocked();
-            if (permission) {
-                mPackagesWithBindWidgetPermission.add(packageName);
-            } else {
-                mPackagesWithBindWidgetPermission.remove(packageName);
-            }
-            saveStateAsync();
-        }
-    }
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
 
-    // Binds to a specific RemoteViewsService
-    public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection) {
-        synchronized (mAppWidgetIds) {
-            if (!mHasFeature) {
-                return;
-            }
-            ensureStateLoadedLocked();
-            AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
-            if (id == null) {
-                throw new IllegalArgumentException("bad appWidgetId");
-            }
-            final ComponentName componentName = intent.getComponent();
-            try {
-                final ServiceInfo si = mPm.getServiceInfo(componentName,
-                        PackageManager.GET_PERMISSIONS, mUserId);
-                if (!android.Manifest.permission.BIND_REMOTEVIEWS.equals(si.permission)) {
-                    throw new SecurityException("Selected service does not require "
-                            + android.Manifest.permission.BIND_REMOTEVIEWS + ": " + componentName);
-                }
-            } catch (RemoteException e) {
-                throw new IllegalArgumentException("Unknown component " + componentName);
+            // NOTE: The lookup is enforcing security across users by making
+            // sure the caller can only access widgets it hosts or provides.
+            Widget widget = lookupWidgetLocked(appWidgetId,
+                    Binder.getCallingUid(), callingPackage);
+
+            if (widget == null) {
+                throw new IllegalArgumentException("Bad widget id");
             }
 
-            // Ensure that the service specified by the passed intent belongs to the same package
-            // as provides the passed widget id.
-            String widgetIdPackage = id.provider.info.provider.getPackageName();
+            // Make sure the widget has a provider.
+            if (widget.provider == null) {
+                throw new IllegalArgumentException("No provider for widget "
+                        + appWidgetId);
+            }
+
+            ComponentName componentName = intent.getComponent();
+
+            // Ensure that the service belongs to the same package as the provider.
+            // But this is not enough as they may be under different users - see below...
+            String providerPackage = widget.provider.id.componentName.getPackageName();
             String servicePackage = componentName.getPackageName();
-            if (!servicePackage.equals(widgetIdPackage)) {
-                throw new SecurityException("Specified intent doesn't belong to the same package"
-                        + " as the provided AppWidget id");
+            if (!servicePackage.equals(providerPackage)) {
+                throw new SecurityException("The taget service not in the same package"
+                        + " as the widget provider");
             }
 
-            // If there is already a connection made for this service intent, then disconnect from
-            // that first. (This does not allow multiple connections to the same service under
-            // the same key)
-            ServiceConnectionProxy conn = null;
+            // Make sure this service exists under the same user as the provider and
+            // requires a permission which allows only the system to bind to it.
+            mSecurityPolicy.enforceServiceExistsAndRequiresBindRemoteViewsPermission(
+                    componentName, widget.provider.getUserId());
+
+            // Good to go - the service pakcage is correct, it exists for the correct
+            // user, and requires the bind permission.
+
+            // If there is already a connection made for this service intent, then
+            // disconnect from that first. (This does not allow multiple connections
+            // to the same service under the same key).
+            ServiceConnectionProxy connection = null;
             FilterComparison fc = new FilterComparison(intent);
             Pair<Integer, FilterComparison> key = Pair.create(appWidgetId, fc);
+
             if (mBoundRemoteViewsServices.containsKey(key)) {
-                conn = (ServiceConnectionProxy) mBoundRemoteViewsServices.get(key);
-                conn.disconnect();
-                mContext.unbindService(conn);
+                connection = (ServiceConnectionProxy) mBoundRemoteViewsServices.get(key);
+                connection.disconnect();
+                unbindService(connection);
                 mBoundRemoteViewsServices.remove(key);
             }
 
-            int userId = UserHandle.getUserId(id.provider.uid);
-            if (userId != mUserId) {
-                Slog.w(TAG, "AppWidgetServiceImpl of user " + mUserId
-                        + " binding to provider on user " + userId);
-            }
             // Bind to the RemoteViewsService (which will trigger a callback to the
             // RemoteViewsAdapter.onServiceConnected())
-            final long token = Binder.clearCallingIdentity();
-            try {
-                conn = new ServiceConnectionProxy(key, connection);
-                mContext.bindServiceAsUser(intent, conn, Context.BIND_AUTO_CREATE,
-                        new UserHandle(userId));
-                mBoundRemoteViewsServices.put(key, conn);
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
+            connection = new ServiceConnectionProxy(callbacks);
+            bindService(intent, connection, widget.provider.info.getProfile());
+            mBoundRemoteViewsServices.put(key, connection);
 
-            // Add it to the mapping of RemoteViewsService to appWidgetIds so that we can determine
-            // when we can call back to the RemoteViewsService later to destroy associated
-            // factories.
-            incrementAppWidgetServiceRefCount(appWidgetId, fc);
+            // Add it to the mapping of RemoteViewsService to appWidgetIds so that we
+            // can determine when we can call back to the RemoteViewsService later to
+            // destroy associated factories.
+            Pair<Integer, FilterComparison> serviceId = Pair.create(widget.provider.id.uid, fc);
+            incrementAppWidgetServiceRefCount(appWidgetId, serviceId);
         }
     }
 
-    // Unbinds from a specific RemoteViewsService
-    public void unbindRemoteViewsService(int appWidgetId, Intent intent) {
-        synchronized (mAppWidgetIds) {
-            if (!mHasFeature) {
-                return;
-            }
-            ensureStateLoadedLocked();
+    @Override
+    public void unbindRemoteViewsService(String callingPackage, int appWidgetId, Intent intent) {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (DEBUG) {
+            Slog.i(TAG, "unbindRemoteViewsService() " + userId);
+        }
+
+        // Make sure the package runs under the caller uid.
+        mSecurityPolicy.enforceCallFromPackage(callingPackage);
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
             // Unbind from the RemoteViewsService (which will trigger a callback to the bound
             // RemoteViewsAdapter)
-            Pair<Integer, FilterComparison> key = Pair.create(appWidgetId, new FilterComparison(
-                    intent));
+            Pair<Integer, FilterComparison> key = Pair.create(appWidgetId,
+                    new FilterComparison(intent));
             if (mBoundRemoteViewsServices.containsKey(key)) {
                 // We don't need to use the appWidgetId until after we are sure there is something
                 // to unbind. Note that this may mask certain issues with apps calling unbind()
                 // more than necessary.
-                AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
-                if (id == null) {
-                    throw new IllegalArgumentException("bad appWidgetId");
+
+                // NOTE: The lookup is enforcing security across users by making
+                // sure the caller can only access widgets it hosts or provides.
+                Widget widget = lookupWidgetLocked(appWidgetId,
+                        Binder.getCallingUid(), callingPackage);
+
+                if (widget == null) {
+                    throw new IllegalArgumentException("Bad widget id " + appWidgetId);
                 }
 
-                ServiceConnectionProxy conn = (ServiceConnectionProxy) mBoundRemoteViewsServices
-                        .get(key);
-                conn.disconnect();
-                mContext.unbindService(conn);
+                ServiceConnectionProxy connection = (ServiceConnectionProxy)
+                        mBoundRemoteViewsServices.get(key);
+                connection.disconnect();
+                mContext.unbindService(connection);
                 mBoundRemoteViewsServices.remove(key);
             }
         }
     }
 
+    @Override
+    public void deleteHost(String callingPackage, int hostId) {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (DEBUG) {
+            Slog.i(TAG, "deleteHost() " + userId);
+        }
+
+        // Make sure the package runs under the caller uid.
+        mSecurityPolicy.enforceCallFromPackage(callingPackage);
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            // NOTE: The lookup is enforcing security across users by making
+            // sure the caller can only access hosts in its uid and package.
+            HostId id = new HostId(Binder.getCallingUid(), hostId, callingPackage);
+            Host host = lookupHostLocked(id);
+
+            if (host == null) {
+                return;
+            }
+
+            deleteHostLocked(host);
+
+            saveGroupStateAsync(userId);
+
+            if (DEBUG) {
+                Slog.i(TAG, "Deleted host " + host.id);
+            }
+        }
+    }
+
+    @Override
+    public void deleteAllHosts() {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (DEBUG) {
+            Slog.i(TAG, "deleteAllHosts() " + userId);
+        }
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            boolean changed = false;
+
+            final int N = mHosts.size();
+            for (int i = N - 1; i >= 0; i--) {
+                Host host = mHosts.get(i);
+
+                // Delete only hosts in the calling uid.
+                if (host.id.uid == Binder.getCallingUid()) {
+                    deleteHostLocked(host);
+                    changed = true;
+
+                    if (DEBUG) {
+                        Slog.i(TAG, "Deleted host " + host.id);
+                    }
+                }
+            }
+
+            if (changed) {
+                saveGroupStateAsync(userId);
+            }
+        }
+    }
+
+    @Override
+    public AppWidgetProviderInfo getAppWidgetInfo(String callingPackage, int appWidgetId) {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (DEBUG) {
+            Slog.i(TAG, "getAppWidgetInfo() " + userId);
+        }
+
+        // Make sure the package runs under the caller uid.
+        mSecurityPolicy.enforceCallFromPackage(callingPackage);
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            // NOTE: The lookup is enforcing security across users by making
+            // sure the caller can only access widgets it hosts or provides.
+            Widget widget = lookupWidgetLocked(appWidgetId,
+                    Binder.getCallingUid(), callingPackage);
+
+            if (widget != null && widget.provider != null && !widget.provider.zombie) {
+                return cloneIfLocalBinder(widget.provider.info);
+            }
+
+            return null;
+        }
+    }
+
+    @Override
+    public RemoteViews getAppWidgetViews(String callingPackage, int appWidgetId) {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (DEBUG) {
+            Slog.i(TAG, "getAppWidgetViews() " + userId);
+        }
+
+        // Make sure the package runs under the caller uid.
+        mSecurityPolicy.enforceCallFromPackage(callingPackage);
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            // NOTE: The lookup is enforcing security across users by making
+            // sure the caller can only access widgets it hosts or provides.
+            Widget widget = lookupWidgetLocked(appWidgetId,
+                    Binder.getCallingUid(), callingPackage);
+
+            if (widget != null) {
+                return cloneIfLocalBinder(widget.views);
+            }
+
+            return null;
+        }
+    }
+
+    @Override
+    public void updateAppWidgetOptions(String callingPackage, int appWidgetId, Bundle options) {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (DEBUG) {
+            Slog.i(TAG, "updateAppWidgetOptions() " + userId);
+        }
+
+        // Make sure the package runs under the caller uid.
+        mSecurityPolicy.enforceCallFromPackage(callingPackage);
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            // NOTE: The lookup is enforcing security across users by making
+            // sure the caller can only access widgets it hosts or provides.
+            Widget widget = lookupWidgetLocked(appWidgetId,
+                    Binder.getCallingUid(), callingPackage);
+
+            if (widget == null) {
+                return;
+            }
+
+            // Merge the options.
+            widget.options.putAll(options);
+
+            // Send the broacast to notify the provider that options changed.
+            sendOptionsChangedIntentLocked(widget);
+
+            saveGroupStateAsync(userId);
+        }
+    }
+
+    @Override
+    public Bundle getAppWidgetOptions(String callingPackage, int appWidgetId) {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (DEBUG) {
+            Slog.i(TAG, "getAppWidgetOptions() " + userId);
+        }
+
+        // Make sure the package runs under the caller uid.
+        mSecurityPolicy.enforceCallFromPackage(callingPackage);
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            // NOTE: The lookup is enforcing security across users by making
+            // sure the caller can only access widgets it hosts or provides.
+            Widget widget = lookupWidgetLocked(appWidgetId,
+                    Binder.getCallingUid(), callingPackage);
+
+            if (widget != null && widget.options != null) {
+                return cloneIfLocalBinder(widget.options);
+            }
+
+            return Bundle.EMPTY;
+        }
+    }
+
+    @Override
+    public void updateAppWidgetIds(String callingPackage, int[] appWidgetIds,
+            RemoteViews views) {
+        if (DEBUG) {
+            Slog.i(TAG, "updateAppWidgetIds() " + UserHandle.getCallingUserId());
+        }
+
+        updateAppWidgetIds(callingPackage, appWidgetIds, views, false);
+    }
+
+    @Override
+    public void partiallyUpdateAppWidgetIds(String callingPackage, int[] appWidgetIds,
+            RemoteViews views) {
+        if (DEBUG) {
+            Slog.i(TAG, "partiallyUpdateAppWidgetIds() " + UserHandle.getCallingUserId());
+        }
+
+        updateAppWidgetIds(callingPackage, appWidgetIds, views, true);
+    }
+
+    @Override
+    public void notifyAppWidgetViewDataChanged(String callingPackage, int[] appWidgetIds,
+            int viewId) {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (DEBUG) {
+            Slog.i(TAG, "notifyAppWidgetViewDataChanged() " + userId);
+        }
+
+        // Make sure the package runs under the caller uid.
+        mSecurityPolicy.enforceCallFromPackage(callingPackage);
+
+        if (appWidgetIds == null || appWidgetIds.length == 0) {
+            return;
+        }
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            final int N = appWidgetIds.length;
+            for (int i = 0; i < N; i++) {
+                final int appWidgetId = appWidgetIds[i];
+
+                // NOTE: The lookup is enforcing security across users by making
+                // sure the caller can only access widgets it hosts or provides.
+                Widget widget = lookupWidgetLocked(appWidgetId,
+                        Binder.getCallingUid(), callingPackage);
+
+                if (widget != null) {
+                    scheduleNotifyAppWidgetViewDataChanged(widget, viewId);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void updateAppWidgetProvider(ComponentName componentName, RemoteViews views) {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (DEBUG) {
+            Slog.i(TAG, "updateAppWidgetProvider() " + userId);
+        }
+
+        // Make sure the package runs under the caller uid.
+        mSecurityPolicy.enforceCallFromPackage(componentName.getPackageName());
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            // NOTE: The lookup is enforcing security across users by making
+            // sure the caller can access only its providers.
+            ProviderId providerId = new ProviderId(Binder.getCallingUid(), componentName);
+            Provider provider = lookupProviderLocked(providerId);
+
+            if (provider == null) {
+                Slog.w(TAG, "Provider doesn't exist " + providerId);
+                return;
+            }
+
+            ArrayList<Widget> instances = provider.widgets;
+            final int N = instances.size();
+            for (int i = 0; i < N; i++) {
+                Widget widget = instances.get(i);
+                updateAppWidgetInstanceLocked(widget, views, false);
+            }
+        }
+    }
+
+    @Override
+    public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter, int[] profileIds) {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (DEBUG) {
+            Slog.i(TAG, "getInstalledProvidersForProfiles() " + userId);
+        }
+
+        if (profileIds != null && profileIds.length > 0) {
+            // Make sure the profile ids are children of the calling user.
+            profileIds = mSecurityPolicy.resolveCallerEnabledGroupProfiles(profileIds);
+        } else {
+            profileIds = new int[] {userId};
+        }
+
+        if (profileIds.length == 0) {
+            return null;
+        }
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            ArrayList<AppWidgetProviderInfo> result = new ArrayList<>();
+
+            final int providerCount = mProviders.size();
+            for (int i = 0; i < providerCount; i++) {
+                Provider provider = mProviders.get(i);
+                AppWidgetProviderInfo info = provider.info;
+
+                // Ignore an invalid provider or one not matching the filter.
+                if (provider.zombie || (info.widgetCategory & categoryFilter) == 0) {
+                    continue;
+                }
+
+                // Add providers only for the requested profiles ...
+                final int providerProfileId = info.getProfile().getIdentifier();
+                final int profileCount = profileIds.length;
+                for (int j = 0; j < profileCount; j++) {
+                    final int profileId = profileIds[j];
+                    if (providerProfileId == profileId) {
+                        // ... that are white-listed by the profile manager.
+                        if (mSecurityPolicy.isProviderInCallerOrInProfileAndWhitelListed(
+                                provider.id.componentName.getPackageName(), providerProfileId)) {
+                            result.add(cloneIfLocalBinder(info));
+                        }
+                        break;
+                    }
+                }
+            }
+
+            return result;
+        }
+    }
+
+    private void updateAppWidgetIds(String callingPackage, int[] appWidgetIds,
+            RemoteViews views, boolean partially) {
+        final int userId = UserHandle.getCallingUserId();
+
+        if (appWidgetIds == null || appWidgetIds.length == 0) {
+            return;
+        }
+
+        // Make sure the package runs under the caller uid.
+        mSecurityPolicy.enforceCallFromPackage(callingPackage);
+
+        final int bitmapMemoryUsage = (views != null) ? views.estimateMemoryUsage() : 0;
+        if (bitmapMemoryUsage > mMaxWidgetBitmapMemory) {
+            throw new IllegalArgumentException("RemoteViews for widget update exceeds"
+                    + " maximum bitmap memory usage (used: " + bitmapMemoryUsage
+                    + ", max: " + mMaxWidgetBitmapMemory + ")");
+        }
+
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            final int N = appWidgetIds.length;
+            for (int i = 0; i < N; i++) {
+                final int appWidgetId = appWidgetIds[i];
+
+                // NOTE: The lookup is enforcing security across users by making
+                // sure the caller can only access widgets it hosts or provides.
+                Widget widget = lookupWidgetLocked(appWidgetId,
+                        Binder.getCallingUid(), callingPackage);
+
+                if (widget != null) {
+                    updateAppWidgetInstanceLocked(widget, views, partially);
+                }
+            }
+        }
+    }
+
+    private int incrementAndGetAppWidgetIdLocked(int userId) {
+        final int appWidgetId = peekNextAppWidgetIdLocked(userId) + 1;
+        mNextAppWidgetIds.put(userId, appWidgetId);
+        return appWidgetId;
+    }
+
+    private void setMinAppWidgetIdLocked(int userId, int minWidgetId) {
+        final int nextAppWidgetId = peekNextAppWidgetIdLocked(userId);
+        if (nextAppWidgetId < minWidgetId) {
+            mNextAppWidgetIds.put(userId, minWidgetId);
+        }
+    }
+
+    private int peekNextAppWidgetIdLocked(int userId) {
+        if (mNextAppWidgetIds.indexOfKey(userId) < 0) {
+            return AppWidgetManager.INVALID_APPWIDGET_ID + 1;
+        } else {
+            return mNextAppWidgetIds.get(userId);
+        }
+    }
+
+    private Host lookupOrAddHostLocked(HostId id) {
+        Host host = lookupHostLocked(id);
+        if (host != null) {
+            return host;
+        }
+
+        host = new Host();
+        host.id = id;
+        mHosts.add(host);
+
+        return host;
+    }
+
+    private void deleteHostLocked(Host host) {
+        final int N = host.widgets.size();
+        for (int i = N - 1; i >= 0; i--) {
+            Widget widget = host.widgets.remove(i);
+            deleteAppWidgetLocked(widget);
+        }
+        mHosts.remove(host);
+
+        // it's gone or going away, abruptly drop the callback connection
+        host.callbacks = null;
+    }
+
+    private void deleteAppWidgetLocked(Widget widget) {
+        // We first unbind all services that are bound to this id
+        unbindAppWidgetRemoteViewsServicesLocked(widget);
+
+        Host host = widget.host;
+        host.widgets.remove(widget);
+        pruneHostLocked(host);
+
+        mWidgets.remove(widget);
+
+        Provider provider = widget.provider;
+        if (provider != null) {
+            provider.widgets.remove(widget);
+            if (!provider.zombie) {
+                // send the broacast saying that this appWidgetId has been deleted
+                sendDeletedIntentLocked(widget);
+
+                if (provider.widgets.isEmpty()) {
+                    // cancel the future updates
+                    cancelBroadcasts(provider);
+
+                    // send the broacast saying that the provider is not in use any more
+                    sendDisabledIntentLocked(provider);
+                }
+            }
+        }
+    }
+
+    private void cancelBroadcasts(Provider provider) {
+        if (DEBUG) {
+            Slog.i(TAG, "cancelBroadcasts() for " + provider);
+        }
+        if (provider.broadcast != null) {
+            mAlarmManager.cancel(provider.broadcast);
+            long token = Binder.clearCallingIdentity();
+            try {
+                provider.broadcast.cancel();
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+            provider.broadcast = null;
+        }
+    }
+
     // Unbinds from a RemoteViewsService when we delete an app widget
-    private void unbindAppWidgetRemoteViewsServicesLocked(AppWidgetId id) {
-        int appWidgetId = id.appWidgetId;
+    private void unbindAppWidgetRemoteViewsServicesLocked(Widget widget) {
+        int appWidgetId = widget.appWidgetId;
         // Unbind all connections to Services bound to this AppWidgetId
         Iterator<Pair<Integer, Intent.FilterComparison>> it = mBoundRemoteViewsServices.keySet()
                 .iterator();
         while (it.hasNext()) {
             final Pair<Integer, Intent.FilterComparison> key = it.next();
-            if (key.first.intValue() == appWidgetId) {
-                final ServiceConnectionProxy conn = (ServiceConnectionProxy) mBoundRemoteViewsServices
-                        .get(key);
+            if (key.first == appWidgetId) {
+                final ServiceConnectionProxy conn = (ServiceConnectionProxy)
+                        mBoundRemoteViewsServices.get(key);
                 conn.disconnect();
                 mContext.unbindService(conn);
                 it.remove();
@@ -937,337 +1508,132 @@
 
         // Check if we need to destroy any services (if no other app widgets are
         // referencing the same service)
-        decrementAppWidgetServiceRefCount(id);
+        decrementAppWidgetServiceRefCount(widget);
     }
 
     // Destroys the cached factory on the RemoteViewsService's side related to the specified intent
-    private void destroyRemoteViewsService(final Intent intent, AppWidgetId id) {
+    private void destroyRemoteViewsService(final Intent intent, Widget widget) {
         final ServiceConnection conn = new ServiceConnection() {
             @Override
             public void onServiceConnected(ComponentName name, IBinder service) {
                 final IRemoteViewsFactory cb = IRemoteViewsFactory.Stub.asInterface(service);
                 try {
                     cb.onDestroy(intent);
-                } catch (RemoteException e) {
-                    e.printStackTrace();
-                } catch (RuntimeException e) {
-                    e.printStackTrace();
+                } catch (RemoteException re) {
+                    Slog.e(TAG, "Error calling remove view factory", re);
                 }
                 mContext.unbindService(this);
             }
 
             @Override
-            public void onServiceDisconnected(android.content.ComponentName name) {
+            public void onServiceDisconnected(ComponentName name) {
                 // Do nothing
             }
         };
 
-        int userId = UserHandle.getUserId(id.provider.uid);
         // Bind to the service and remove the static intent->factory mapping in the
         // RemoteViewsService.
         final long token = Binder.clearCallingIdentity();
         try {
             mContext.bindServiceAsUser(intent, conn, Context.BIND_AUTO_CREATE,
-                    new UserHandle(userId));
+                    widget.provider.info.getProfile());
         } finally {
             Binder.restoreCallingIdentity(token);
         }
     }
 
     // Adds to the ref-count for a given RemoteViewsService intent
-    private void incrementAppWidgetServiceRefCount(int appWidgetId, FilterComparison fc) {
+    private void incrementAppWidgetServiceRefCount(int appWidgetId,
+            Pair<Integer, FilterComparison> serviceId) {
         HashSet<Integer> appWidgetIds = null;
-        if (mRemoteViewsServicesAppWidgets.containsKey(fc)) {
-            appWidgetIds = mRemoteViewsServicesAppWidgets.get(fc);
+        if (mRemoteViewsServicesAppWidgets.containsKey(serviceId)) {
+            appWidgetIds = mRemoteViewsServicesAppWidgets.get(serviceId);
         } else {
-            appWidgetIds = new HashSet<Integer>();
-            mRemoteViewsServicesAppWidgets.put(fc, appWidgetIds);
+            appWidgetIds = new HashSet<>();
+            mRemoteViewsServicesAppWidgets.put(serviceId, appWidgetIds);
         }
         appWidgetIds.add(appWidgetId);
     }
 
     // Subtracts from the ref-count for a given RemoteViewsService intent, prompting a delete if
     // the ref-count reaches zero.
-    private void decrementAppWidgetServiceRefCount(AppWidgetId id) {
-        Iterator<FilterComparison> it = mRemoteViewsServicesAppWidgets.keySet().iterator();
+    private void decrementAppWidgetServiceRefCount(Widget widget) {
+        Iterator<Pair<Integer, FilterComparison>> it = mRemoteViewsServicesAppWidgets
+                .keySet().iterator();
         while (it.hasNext()) {
-            final FilterComparison key = it.next();
+            final Pair<Integer, FilterComparison> key = it.next();
             final HashSet<Integer> ids = mRemoteViewsServicesAppWidgets.get(key);
-            if (ids.remove(id.appWidgetId)) {
+            if (ids.remove(widget.appWidgetId)) {
                 // If we have removed the last app widget referencing this service, then we
                 // should destroy it and remove it from this set
                 if (ids.isEmpty()) {
-                    destroyRemoteViewsService(key.getIntent(), id);
+                    destroyRemoteViewsService(key.second.getIntent(), widget);
                     it.remove();
                 }
             }
         }
     }
 
-    public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) {
-        synchronized (mAppWidgetIds) {
-            if (!mHasFeature) {
-                return null;
-            }
-            ensureStateLoadedLocked();
-            AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
-            if (id != null && id.provider != null && !id.provider.zombie) {
-                return cloneIfLocalBinder(id.provider.info);
-            }
-            return null;
-        }
+    private void saveGroupStateAsync(int groupId) {
+        mSaveStateHandler.post(new SaveStateRunnable(groupId));
     }
 
-    public RemoteViews getAppWidgetViews(int appWidgetId) {
-        if (DBG) log("getAppWidgetViews id=" + appWidgetId);
-        synchronized (mAppWidgetIds) {
-            if (!mHasFeature) {
-                return null;
-            }
-            ensureStateLoadedLocked();
-            AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
-            if (id != null) {
-                return cloneIfLocalBinder(id.views);
-            }
-            if (DBG) log("   couldn't find appwidgetid");
-            return null;
-        }
-    }
+    private void updateAppWidgetInstanceLocked(Widget widget, RemoteViews views,
+            boolean isPartialUpdate) {
+        if (widget != null && widget.provider != null
+                && !widget.provider.zombie && !widget.host.zombie) {
 
-    public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter) {
-        synchronized (mAppWidgetIds) {
-            if (!mHasFeature) {
-                return new ArrayList<AppWidgetProviderInfo>(0);
-            }
-            ensureStateLoadedLocked();
-            final int N = mInstalledProviders.size();
-            ArrayList<AppWidgetProviderInfo> result = new ArrayList<AppWidgetProviderInfo>(N);
-            for (int i = 0; i < N; i++) {
-                Provider p = mInstalledProviders.get(i);
-                if (!p.zombie && (p.info.widgetCategory & categoryFilter) != 0) {
-                    result.add(cloneIfLocalBinder(p.info));
-                }
-            }
-            return result;
-        }
-    }
-
-    public void updateAppWidgetIds(int[] appWidgetIds, RemoteViews views) {
-        if (!mHasFeature) {
-            return;
-        }
-        if (appWidgetIds == null) {
-            return;
-        }
-        if (DBG) log("updateAppWidgetIds views: " + views);
-        int bitmapMemoryUsage = 0;
-        if (views != null) {
-            bitmapMemoryUsage = views.estimateMemoryUsage();
-        }
-        if (bitmapMemoryUsage > mMaxWidgetBitmapMemory) {
-            throw new IllegalArgumentException("RemoteViews for widget update exceeds maximum" +
-                    " bitmap memory usage (used: " + bitmapMemoryUsage + ", max: " +
-                    mMaxWidgetBitmapMemory + ") The total memory cannot exceed that required to" +
-                    " fill the device's screen once.");
-        }
-
-        if (appWidgetIds.length == 0) {
-            return;
-        }
-        final int N = appWidgetIds.length;
-
-        synchronized (mAppWidgetIds) {
-            ensureStateLoadedLocked();
-            for (int i = 0; i < N; i++) {
-                AppWidgetId id = lookupAppWidgetIdLocked(appWidgetIds[i]);
-                updateAppWidgetInstanceLocked(id, views);
-            }
-        }
-    }
-
-    private void saveStateAsync() {
-        mSaveStateHandler.post(mSaveStateRunnable);
-    }
-
-    private final Runnable mSaveStateRunnable = new Runnable() {
-        @Override
-        public void run() {
-            synchronized (mAppWidgetIds) {
-                ensureStateLoadedLocked();
-                saveStateLocked();
-            }
-        }
-    };
-
-    public void updateAppWidgetOptions(int appWidgetId, Bundle options) {
-        synchronized (mAppWidgetIds) {
-            if (!mHasFeature) {
-                return;
-            }
-            ensureStateLoadedLocked();
-            AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
-
-            if (id == null) {
-                return;
-            }
-
-            Provider p = id.provider;
-            // Merge the options
-            id.options.putAll(cloneIfLocalBinder(options));
-
-            // send the broacast saying that this appWidgetId has been deleted
-            Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED);
-            intent.setComponent(p.info.provider);
-            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id.appWidgetId);
-            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, id.options);
-            mContext.sendBroadcastAsUser(intent, new UserHandle(mUserId));
-            saveStateAsync();
-        }
-    }
-
-    public Bundle getAppWidgetOptions(int appWidgetId) {
-        synchronized (mAppWidgetIds) {
-            if (!mHasFeature) {
-                return Bundle.EMPTY;
-            }
-            ensureStateLoadedLocked();
-            AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
-            if (id != null && id.options != null) {
-                return cloneIfLocalBinder(id.options);
-            } else {
-                return Bundle.EMPTY;
-            }
-        }
-    }
-
-    public void partiallyUpdateAppWidgetIds(int[] appWidgetIds, RemoteViews views) {
-        if (!mHasFeature) {
-            return;
-        }
-        if (appWidgetIds == null) {
-            return;
-        }
-        if (appWidgetIds.length == 0) {
-            return;
-        }
-        final int N = appWidgetIds.length;
-
-        synchronized (mAppWidgetIds) {
-            ensureStateLoadedLocked();
-            for (int i = 0; i < N; i++) {
-                AppWidgetId id = lookupAppWidgetIdLocked(appWidgetIds[i]);
-                if (id == null) {
-                    Slog.w(TAG, "widget id " + appWidgetIds[i] + " not found!");
-                } else if (id.views != null) {
-                    // Only trigger a partial update for a widget if it has received a full update
-                    updateAppWidgetInstanceLocked(id, views, true);
-                }
-            }
-        }
-    }
-
-    public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId) {
-        if (!mHasFeature) {
-            return;
-        }
-        if (appWidgetIds == null) {
-            return;
-        }
-        if (appWidgetIds.length == 0) {
-            return;
-        }
-        final int N = appWidgetIds.length;
-
-        synchronized (mAppWidgetIds) {
-            ensureStateLoadedLocked();
-            for (int i = 0; i < N; i++) {
-                AppWidgetId id = lookupAppWidgetIdLocked(appWidgetIds[i]);
-                notifyAppWidgetViewDataChangedInstanceLocked(id, viewId);
-            }
-        }
-    }
-
-    public void updateAppWidgetProvider(ComponentName provider, RemoteViews views) {
-        if (!mHasFeature) {
-            return;
-        }
-        synchronized (mAppWidgetIds) {
-            ensureStateLoadedLocked();
-            Provider p = lookupProviderLocked(provider);
-            if (p == null) {
-                Slog.w(TAG, "updateAppWidgetProvider: provider doesn't exist: " + provider);
-                return;
-            }
-            ArrayList<AppWidgetId> instances = p.instances;
-            final int callingUid = Binder.getCallingUid();
-            final int N = instances.size();
-            for (int i = 0; i < N; i++) {
-                AppWidgetId id = instances.get(i);
-                if (canAccessAppWidgetId(id, callingUid)) {
-                    updateAppWidgetInstanceLocked(id, views);
-                }
-            }
-        }
-    }
-
-    void updateAppWidgetInstanceLocked(AppWidgetId id, RemoteViews views) {
-        updateAppWidgetInstanceLocked(id, views, false);
-    }
-
-    void updateAppWidgetInstanceLocked(AppWidgetId id, RemoteViews views, boolean isPartialUpdate) {
-        // allow for stale appWidgetIds and other badness
-        // lookup also checks that the calling process can access the appWidgetId
-        // drop unbound appWidgetIds (shouldn't be possible under normal circumstances)
-        if (id != null && id.provider != null && !id.provider.zombie && !id.host.zombie) {
-
-            if (!isPartialUpdate) {
-                // For a full update we replace the RemoteViews completely.
-                id.views = views;
-            } else {
+            if (isPartialUpdate && widget.views != null) {
                 // For a partial update, we merge the new RemoteViews with the old.
-                id.views.mergeRemoteViews(views);
+                widget.views.mergeRemoteViews(views);
+            } else {
+                // For a full update we replace the RemoteViews completely.
+                widget.views = views;
             }
 
-            // is anyone listening?
-            if (id.host.callbacks != null) {
-                try {
-                    // the lock is held, but this is a oneway call
-                    id.host.callbacks.updateAppWidget(id.appWidgetId, views, mUserId);
-                } catch (RemoteException e) {
-                    // It failed; remove the callback. No need to prune because
-                    // we know that this host is still referenced by this instance.
-                    id.host.callbacks = null;
-                }
-            }
+            scheduleNotifyUpdateAppWidgetLocked(widget);
         }
     }
 
-    void notifyAppWidgetViewDataChangedInstanceLocked(AppWidgetId id, int viewId) {
-        // allow for stale appWidgetIds and other badness
-        // lookup also checks that the calling process can access the appWidgetId
-        // drop unbound appWidgetIds (shouldn't be possible under normal circumstances)
-        if (id != null && id.provider != null && !id.provider.zombie && !id.host.zombie) {
-            // is anyone listening?
-            if (id.host.callbacks != null) {
-                try {
-                    // the lock is held, but this is a oneway call
-                    id.host.callbacks.viewDataChanged(id.appWidgetId, viewId, mUserId);
-                } catch (RemoteException e) {
-                    // It failed; remove the callback. No need to prune because
-                    // we know that this host is still referenced by this instance.
-                    id.host.callbacks = null;
-                }
-            }
+    private void scheduleNotifyAppWidgetViewDataChanged(Widget widget, int viewId) {
+        if (widget == null || widget.host == null || widget.host.zombie
+                || widget.host.callbacks == null || widget.provider == null
+                || widget.provider.zombie) {
+            return;
+        }
 
-            // If the host is unavailable, then we call the associated
-            // RemoteViewsFactory.onDataSetChanged() directly
-            if (id.host.callbacks == null) {
-                Set<FilterComparison> keys = mRemoteViewsServicesAppWidgets.keySet();
-                for (FilterComparison key : keys) {
-                    if (mRemoteViewsServicesAppWidgets.get(key).contains(id.appWidgetId)) {
-                        Intent intent = key.getIntent();
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = widget.host;
+        args.arg2 = widget.host.callbacks;
+        args.argi1 = widget.appWidgetId;
+        args.argi2 = viewId;
 
-                        final ServiceConnection conn = new ServiceConnection() {
+        mCallbackHandler.obtainMessage(
+                CallbackHandler.MSG_NOTIFY_VIEW_DATA_CHANGED,
+                args).sendToTarget();
+    }
+
+
+    private void handleNotifyAppWidgetViewDataChanged(Host host, IAppWidgetHost callbacks,
+            int appWidgetId, int viewId) {
+        try {
+            callbacks.viewDataChanged(appWidgetId, viewId);
+        } catch (RemoteException re) {
+            // It failed; remove the callback. No need to prune because
+            // we know that this host is still referenced by this instance.
+            callbacks = null;
+        }
+
+        // If the host is unavailable, then we call the associated
+        // RemoteViewsFactory.onDataSetChanged() directly
+        synchronized (mLock) {
+            if (callbacks == null) {
+                host.callbacks = null;
+
+                Set<Pair<Integer, FilterComparison>> keys = mRemoteViewsServicesAppWidgets.keySet();
+                for (Pair<Integer, FilterComparison> key : keys) {
+                    if (mRemoteViewsServicesAppWidgets.get(key).contains(appWidgetId)) {
+                        final ServiceConnection connection = new ServiceConnection() {
                             @Override
                             public void onServiceConnected(ComponentName name, IBinder service) {
                                 IRemoteViewsFactory cb = IRemoteViewsFactory.Stub
@@ -1275,9 +1641,7 @@
                                 try {
                                     cb.onDataSetChangedAsync();
                                 } catch (RemoteException e) {
-                                    e.printStackTrace();
-                                } catch (RuntimeException e) {
-                                    e.printStackTrace();
+                                    Slog.e(TAG, "Error calling onDataSetChangedAsync()", e);
                                 }
                                 mContext.unbindService(this);
                             }
@@ -1288,40 +1652,124 @@
                             }
                         };
 
-                        int userId = UserHandle.getUserId(id.provider.uid);
+                        final int userId = UserHandle.getUserId(key.first);
+                        Intent intent = key.second.getIntent();
+
                         // Bind to the service and call onDataSetChanged()
-                        final long token = Binder.clearCallingIdentity();
-                        try {
-                            mContext.bindServiceAsUser(intent, conn, Context.BIND_AUTO_CREATE,
-                                    new UserHandle(userId));
-                        } finally {
-                            Binder.restoreCallingIdentity(token);
-                        }
+                        bindService(intent, connection, new UserHandle(userId));
                     }
                 }
             }
         }
     }
 
-    private boolean isLocalBinder() {
+    private void scheduleNotifyUpdateAppWidgetLocked(Widget widget) {
+        if (widget == null || widget.provider == null || widget.provider.zombie
+                || widget.host.callbacks == null || widget.host.zombie) {
+            return;
+        }
+
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = widget.host;
+        args.arg2 = widget.host.callbacks;
+        args.arg3 = widget.views;
+        args.argi1 = widget.appWidgetId;
+
+        mCallbackHandler.obtainMessage(
+                CallbackHandler.MSG_NOTIFY_UPDATE_APP_WIDGET,
+                args).sendToTarget();
+    }
+
+    private void handleNotifyUpdateAppWidget(Host host, IAppWidgetHost callbacks,
+            int appWidgetId, RemoteViews views) {
+        try {
+            callbacks.updateAppWidget(appWidgetId, views);
+        } catch (RemoteException re) {
+            synchronized (mLock) {
+                Slog.e(TAG, "Widget host dead: " + host.id, re);
+                host.callbacks = null;
+            }
+        }
+    }
+
+    private void scheduleNotifyProviderChangedLocked(Widget widget) {
+        if (widget == null || widget.provider == null || widget.provider.zombie
+                || widget.host.callbacks == null || widget.host.zombie) {
+            return;
+        }
+
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = widget.host;
+        args.arg2 = widget.host.callbacks;
+        args.arg3 = widget.provider.info;
+        args.argi1 = widget.appWidgetId;
+
+        mCallbackHandler.obtainMessage(
+                CallbackHandler.MSG_NOTIFY_PROVIDER_CHANGED,
+                args).sendToTarget();
+    }
+
+    private void handleNotifyProviderChanged(Host host, IAppWidgetHost callbacks,
+            int appWidgetId, AppWidgetProviderInfo info) {
+        try {
+            callbacks.providerChanged(appWidgetId, info);
+        } catch (RemoteException re) {
+            synchronized (mLock){
+                Slog.e(TAG, "Widget host dead: " + host.id, re);
+                host.callbacks = null;
+            }
+        }
+    }
+
+    private void scheduleNotifyHostsForProvidersChangedLocked() {
+        final int N = mHosts.size();
+        for (int i = N - 1; i >= 0; i--) {
+            Host host = mHosts.get(i);
+
+            if (host == null || host.zombie || host.callbacks == null) {
+                continue;
+            }
+
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = host;
+            args.arg2 = host.callbacks;
+
+            mCallbackHandler.obtainMessage(
+                    CallbackHandler.MSG_NOTIFY_PROVIDERS_CHANGED,
+                    args).sendToTarget();
+        }
+    }
+
+    private void handleNotifyProvidersChanged(Host host, IAppWidgetHost callbacks) {
+        try {
+            callbacks.providersChanged();
+        } catch (RemoteException re) {
+            synchronized (mLock) {
+                Slog.e(TAG, "Widget host dead: " + host.id, re);
+                host.callbacks = null;
+            }
+        }
+    }
+
+    private static boolean isLocalBinder() {
         return Process.myPid() == Binder.getCallingPid();
     }
 
-    private RemoteViews cloneIfLocalBinder(RemoteViews rv) {
+    private static RemoteViews cloneIfLocalBinder(RemoteViews rv) {
         if (isLocalBinder() && rv != null) {
             return rv.clone();
         }
         return rv;
     }
 
-    private AppWidgetProviderInfo cloneIfLocalBinder(AppWidgetProviderInfo info) {
+    private static AppWidgetProviderInfo cloneIfLocalBinder(AppWidgetProviderInfo info) {
         if (isLocalBinder() && info != null) {
             return info.clone();
         }
         return info;
     }
 
-    private Bundle cloneIfLocalBinder(Bundle bundle) {
+    private static Bundle cloneIfLocalBinder(Bundle bundle) {
         // Note: this is only a shallow copy. For now this will be fine, but it could be problematic
         // if we start adding objects to the options. Further, it would only be an issue if keyguard
         // used such options.
@@ -1331,832 +1779,326 @@
         return bundle;
     }
 
-    public int[] startListening(IAppWidgetHost callbacks, String packageName, int hostId,
-            List<RemoteViews> updatedViews) {
-        if (!mHasFeature) {
-            return new int[0];
-        }
-        int callingUid = enforceCallingUid(packageName);
-        synchronized (mAppWidgetIds) {
-            ensureStateLoadedLocked();
-            Host host = lookupOrAddHostLocked(callingUid, packageName, hostId);
-            host.callbacks = callbacks;
-
-            updatedViews.clear();
-
-            ArrayList<AppWidgetId> instances = host.instances;
-            int N = instances.size();
-            int[] updatedIds = new int[N];
-            for (int i = 0; i < N; i++) {
-                AppWidgetId id = instances.get(i);
-                updatedIds[i] = id.appWidgetId;
-                updatedViews.add(cloneIfLocalBinder(id.views));
-            }
-            return updatedIds;
-        }
-    }
-
-    public void stopListening(int hostId) {
-        synchronized (mAppWidgetIds) {
-            if (!mHasFeature) {
-                return;
-            }
-            ensureStateLoadedLocked();
-            Host host = lookupHostLocked(Binder.getCallingUid(), hostId);
-            if (host != null) {
-                host.callbacks = null;
-                pruneHostLocked(host);
-            }
-        }
-    }
-
-    boolean canAccessAppWidgetId(AppWidgetId id, int callingUid) {
-        if (id.host.uidMatches(callingUid)) {
-            // Apps hosting the AppWidget have access to it.
-            return true;
-        }
-        if (id.provider != null && id.provider.uid == callingUid) {
-            // Apps providing the AppWidget have access to it (if the appWidgetId has been bound)
-            return true;
-        }
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.BIND_APPWIDGET) == PackageManager.PERMISSION_GRANTED) {
-            // Apps that can bind have access to all appWidgetIds.
-            return true;
-        }
-        // Nobody else can access it.
-        return false;
-    }
-
-    AppWidgetId lookupAppWidgetIdLocked(int appWidgetId) {
-        int callingUid = Binder.getCallingUid();
-        final int N = mAppWidgetIds.size();
+    private Widget lookupWidgetLocked(int appWidgetId, int uid, String packageName) {
+        final int N = mWidgets.size();
         for (int i = 0; i < N; i++) {
-            AppWidgetId id = mAppWidgetIds.get(i);
-            if (id.appWidgetId == appWidgetId && canAccessAppWidgetId(id, callingUid)) {
-                return id;
+            Widget widget = mWidgets.get(i);
+            if (widget.appWidgetId == appWidgetId
+                    && mSecurityPolicy.canAccessAppWidget(widget, uid, packageName)) {
+                return widget;
             }
         }
         return null;
     }
 
-    Provider lookupProviderLocked(ComponentName provider) {
-        return lookupProviderLocked(provider, mInstalledProviders);
-    }
-
-    Provider lookupProviderLocked(ComponentName provider, ArrayList<Provider> installedProviders) {
-        final int N = installedProviders.size();
+    private Provider lookupProviderLocked(ProviderId id) {
+        final int N = mProviders.size();
         for (int i = 0; i < N; i++) {
-            Provider p = installedProviders.get(i);
-            if (p.info.provider.equals(provider)) {
-                return p;
+            Provider provider = mProviders.get(i);
+            if (provider.id.equals(id)) {
+                return provider;
             }
         }
         return null;
     }
 
-    Host lookupHostLocked(int uid, int hostId) {
+    private Host lookupHostLocked(HostId hostId) {
         final int N = mHosts.size();
         for (int i = 0; i < N; i++) {
-            Host h = mHosts.get(i);
-            if (h.uidMatches(uid) && h.hostId == hostId) {
-                return h;
+            Host host = mHosts.get(i);
+            if (host.id.equals(hostId)) {
+                return host;
             }
         }
         return null;
     }
 
-    Host lookupOrAddHostLocked(int uid, String packageName, int hostId) {
-        final int N = mHosts.size();
-        for (int i = 0; i < N; i++) {
-            Host h = mHosts.get(i);
-            if (h.hostId == hostId && h.packageName.equals(packageName)) {
-                return h;
+    private void pruneHostLocked(Host host) {
+        if (host.widgets.size() == 0 && host.callbacks == null) {
+            if (DEBUG) {
+                Slog.i(TAG, "Pruning host " + host.id);
             }
-        }
-        Host host = new Host();
-        host.packageName = packageName;
-        host.uid = uid;
-        host.hostId = hostId;
-        mHosts.add(host);
-        return host;
-    }
-
-    void pruneHostLocked(Host host) {
-        if (host.instances.size() == 0 && host.callbacks == null) {
-            if (DBG) log("Pruning host " + host);
             mHosts.remove(host);
         }
     }
 
-    void loadWidgetProviderListLocked() {
+    private void loadGroupWidgetProvidersLocked(int[] profileIds) {
+        List<ResolveInfo> allReceivers = null;
         Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
-        try {
-            List<ResolveInfo> broadcastReceivers = mPm.queryIntentReceivers(intent,
-                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                    PackageManager.GET_META_DATA, mUserId);
 
-            final int N = broadcastReceivers == null ? 0 : broadcastReceivers.size();
-            for (int i = 0; i < N; i++) {
-                ResolveInfo ri = broadcastReceivers.get(i);
-                addProviderLocked(ri);
+        final int profileCount = profileIds.length;
+        for (int i = 0; i < profileCount; i++) {
+            final int profileId = profileIds[i];
+
+            List<ResolveInfo> receivers = queryIntentReceivers(intent, profileId);
+            if (receivers != null && !receivers.isEmpty()) {
+                if (allReceivers == null) {
+                    allReceivers = new ArrayList<>();
+                }
+                allReceivers.addAll(receivers);
             }
-        } catch (RemoteException re) {
-            // Shouldn't happen, local call
+        }
+
+        final int N = (allReceivers == null) ? 0 : allReceivers.size();
+        for (int i = 0; i < N; i++) {
+            ResolveInfo receiver = allReceivers.get(i);
+            addProviderLocked(receiver);
         }
     }
 
-    boolean addProviderLocked(ResolveInfo ri) {
+    private boolean addProviderLocked(ResolveInfo ri) {
         if ((ri.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
             return false;
         }
+
         if (!ri.activityInfo.isEnabled()) {
             return false;
         }
-        Provider p = parseProviderInfoXml(new ComponentName(ri.activityInfo.packageName,
-                ri.activityInfo.name), ri);
-        if (p != null) {
+
+        ComponentName componentName = new ComponentName(ri.activityInfo.packageName,
+                ri.activityInfo.name);
+        ProviderId providerId = new ProviderId(ri.activityInfo.applicationInfo.uid, componentName);
+
+        Provider provider = parseProviderInfoXml(providerId, ri);
+        if (provider != null) {
             // we might have an inactive entry for this provider already due to
             // a preceding restore operation.  if so, fix it up in place; otherwise
             // just add this new one.
-            Provider existing = lookupProviderLocked(p.info.provider);
+            Provider existing = lookupProviderLocked(providerId);
+
+            // If the provider was not found it may be because it was restored and
+            // we did not know its UID so let us find if there is such one.
+            if (existing == null) {
+                providerId = new ProviderId(UNKNOWN_UID, componentName);
+                existing = lookupProviderLocked(providerId);
+            }
+
             if (existing != null) {
                 if (existing.zombie && !mSafeMode) {
                     // it's a placeholder that was set up during an app restore
                     existing.zombie = false;
-                    existing.info = p.info; // the real one filled out from the ResolveInfo
-                    existing.uid = p.uid;
-                    if (DEBUG_BACKUP) {
+                    existing.info = provider.info; // the real one filled out from the ResolveInfo
+                    if (DEBUG) {
                         Slog.i(TAG, "Provider placeholder now reified: " + existing);
                     }
                 }
             } else {
-                mInstalledProviders.add(p);
+                mProviders.add(provider);
             }
             return true;
-        } else {
-            return false;
         }
+
+        return false;
     }
 
-    void removeProviderLocked(int index, Provider p) {
-        int N = p.instances.size();
+    private void deleteProviderLocked(Provider provider) {
+        int N = provider.widgets.size();
         for (int i = 0; i < N; i++) {
-            AppWidgetId id = p.instances.get(i);
+            Widget widget = provider.widgets.remove(i);
             // Call back with empty RemoteViews
-            updateAppWidgetInstanceLocked(id, null);
-            // Stop telling the host about updates for this from now on
-            cancelBroadcasts(p);
+            updateAppWidgetInstanceLocked(widget, null, false);
             // clear out references to this appWidgetId
-            id.host.instances.remove(id);
-            mAppWidgetIds.remove(id);
-            id.provider = null;
-            pruneHostLocked(id.host);
-            id.host = null;
+            widget.host.widgets.remove(widget);
+            mWidgets.remove(widget);
+            widget.provider = null;
+            pruneHostLocked(widget.host);
+            widget.host = null;
         }
-        p.instances.clear();
-        mInstalledProviders.remove(index);
-        mDeletedProviders.add(p);
+        mProviders.remove(provider);
+
         // no need to send the DISABLE broadcast, since the receiver is gone anyway
-        cancelBroadcasts(p);
+        cancelBroadcasts(provider);
     }
 
-    void sendEnableIntentLocked(Provider p) {
+    private void sendEnableIntentLocked(Provider p) {
         Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_ENABLED);
         intent.setComponent(p.info.provider);
-        mContext.sendBroadcastAsUser(intent, new UserHandle(mUserId));
+        sendBroadcastAsUser(intent, p.info.getProfile());
     }
 
-    void sendUpdateIntentLocked(Provider p, int[] appWidgetIds) {
-        if (appWidgetIds != null && appWidgetIds.length > 0) {
-            Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
-            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
-            intent.setComponent(p.info.provider);
-            mContext.sendBroadcastAsUser(intent, new UserHandle(mUserId));
-        }
+    private void sendUpdateIntentLocked(Provider provider, int[] appWidgetIds) {
+        Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
+        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
+        intent.setComponent(provider.info.provider);
+        sendBroadcastAsUser(intent, provider.info.getProfile());
     }
 
-    void registerForBroadcastsLocked(Provider p, int[] appWidgetIds) {
-        if (p.info.updatePeriodMillis > 0) {
+    private void sendDeletedIntentLocked(Widget widget) {
+        Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_DELETED);
+        intent.setComponent(widget.provider.info.provider);
+        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widget.appWidgetId);
+        sendBroadcastAsUser(intent, widget.provider.info.getProfile());
+    }
+
+    private void sendDisabledIntentLocked(Provider provider) {
+        Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_DISABLED);
+        intent.setComponent(provider.info.provider);
+        sendBroadcastAsUser(intent, provider.info.getProfile());
+    }
+
+    public void sendOptionsChangedIntentLocked(Widget widget) {
+        Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED);
+        intent.setComponent(widget.provider.info.provider);
+        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widget.appWidgetId);
+        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, widget.options);
+        sendBroadcastAsUser(intent, widget.provider.info.getProfile());
+    }
+
+    private void registerForBroadcastsLocked(Provider provider, int[] appWidgetIds) {
+        if (provider.info.updatePeriodMillis > 0) {
             // if this is the first instance, set the alarm. otherwise,
             // rely on the fact that we've already set it and that
             // PendingIntent.getBroadcast will update the extras.
-            boolean alreadyRegistered = p.broadcast != null;
+            boolean alreadyRegistered = provider.broadcast != null;
             Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
             intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
-            intent.setComponent(p.info.provider);
+            intent.setComponent(provider.info.provider);
             long token = Binder.clearCallingIdentity();
             try {
-                p.broadcast = PendingIntent.getBroadcastAsUser(mContext, 1, intent,
-                        PendingIntent.FLAG_UPDATE_CURRENT, new UserHandle(mUserId));
+                provider.broadcast = PendingIntent.getBroadcastAsUser(mContext, 1, intent,
+                        PendingIntent.FLAG_UPDATE_CURRENT, provider.info.getProfile());
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
             if (!alreadyRegistered) {
-                long period = p.info.updatePeriodMillis;
+                long period = provider.info.updatePeriodMillis;
                 if (period < MIN_UPDATE_PERIOD) {
                     period = MIN_UPDATE_PERIOD;
                 }
-                mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock
-                        .elapsedRealtime()
-                        + period, period, p.broadcast);
+                mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                        SystemClock.elapsedRealtime() + period, period, provider.broadcast);
             }
         }
     }
 
-    static int[] getAppWidgetIds(Provider p) {
-        int instancesSize = p.instances.size();
+    private static int[] getWidgetIds(ArrayList<Widget> widgets) {
+        int instancesSize = widgets.size();
         int appWidgetIds[] = new int[instancesSize];
         for (int i = 0; i < instancesSize; i++) {
-            appWidgetIds[i] = p.instances.get(i).appWidgetId;
+            appWidgetIds[i] = widgets.get(i).appWidgetId;
         }
         return appWidgetIds;
     }
 
-    public int[] getAppWidgetIds(ComponentName provider) {
-        synchronized (mAppWidgetIds) {
-            ensureStateLoadedLocked();
-            Provider p = lookupProviderLocked(provider);
-            if (p != null && Binder.getCallingUid() == p.uid) {
-                return getAppWidgetIds(p);
-            } else {
-                return new int[0];
-            }
+    private static void dumpProvider(Provider provider, int index, PrintWriter pw) {
+        AppWidgetProviderInfo info = provider.info;
+        pw.print("  ["); pw.print(index); pw.print("] provider ");
+        pw.println(provider.id);
+        pw.print("    min=("); pw.print(info.minWidth);
+        pw.print("x"); pw.print(info.minHeight);
+        pw.print(")   minResize=("); pw.print(info.minResizeWidth);
+        pw.print("x"); pw.print(info.minResizeHeight);
+        pw.print(") updatePeriodMillis=");
+        pw.print(info.updatePeriodMillis);
+        pw.print(" resizeMode=");
+        pw.print(info.resizeMode);
+        pw.print(info.widgetCategory);
+        pw.print(" autoAdvanceViewId=");
+        pw.print(info.autoAdvanceViewId);
+        pw.print(" initialLayout=#");
+        pw.print(Integer.toHexString(info.initialLayout));
+        pw.print(" initialKeyguardLayout=#");
+        pw.print(Integer.toHexString(info.initialKeyguardLayout));
+        pw.print(" zombie="); pw.println(provider.zombie);
+    }
+
+    private static void dumpHost(Host host, int index, PrintWriter pw) {
+        pw.print("  ["); pw.print(index); pw.print("] hostId=");
+        pw.println(host.id);
+        pw.print("    callbacks="); pw.println(host.callbacks);
+        pw.print("    widgets.size="); pw.print(host.widgets.size());
+        pw.print(" zombie="); pw.println(host.zombie);
+    }
+
+    private static void dumpGrant(Pair<Integer, String> grant, int index, PrintWriter pw) {
+        pw.print("  ["); pw.print(index); pw.print(']');
+        pw.print(" user="); pw.print(grant.first);
+        pw.print(" package="); pw.println(grant.second);
+    }
+
+    private static void dumpWidget(Widget widget, int index, PrintWriter pw) {
+        pw.print("  ["); pw.print(index); pw.print("] id=");
+        pw.println(widget.appWidgetId);
+        pw.print("    host=");
+        pw.println(widget.host.id);
+        if (widget.provider != null) {
+            pw.print("    provider="); pw.println(widget.provider.id);
+        }
+        if (widget.host != null) {
+            pw.print("    host.callbacks="); pw.println(widget.host.callbacks);
+        }
+        if (widget.views != null) {
+            pw.print("    views="); pw.println(widget.views);
         }
     }
 
-    static int[] getAppWidgetIds(Host h) {
-        int instancesSize = h.instances.size();
-        int appWidgetIds[] = new int[instancesSize];
-        for (int i = 0; i < instancesSize; i++) {
-            appWidgetIds[i] = h.instances.get(i).appWidgetId;
-        }
-        return appWidgetIds;
-    }
-
-    public int[] getAppWidgetIdsForHost(int hostId) {
-        synchronized (mAppWidgetIds) {
-            ensureStateLoadedLocked();
-            int callingUid = Binder.getCallingUid();
-            Host host = lookupHostLocked(callingUid, hostId);
-            if (host != null) {
-                return getAppWidgetIds(host);
-            } else {
-                return new int[0];
-            }
-        }
-    }
-
-    public List<String> getWidgetParticipants() {
-        HashSet<String> packages = new HashSet<String>();
-        synchronized (mAppWidgetIds) {
-            final int N = mAppWidgetIds.size();
-            for (int i = 0; i < N; i++) {
-                final AppWidgetId id = mAppWidgetIds.get(i);
-                packages.add(id.host.packageName);
-                packages.add(id.provider.info.provider.getPackageName());
-            }
-        }
-        return new ArrayList<String>(packages);
-    }
-
-    private void serializeProvider(XmlSerializer out, Provider p) throws IOException {
+    private static void serializeProvider(XmlSerializer out, Provider p) throws IOException {
         out.startTag(null, "p");
         out.attribute(null, "pkg", p.info.provider.getPackageName());
         out.attribute(null, "cl", p.info.provider.getClassName());
+        out.attribute(null, "tag", Integer.toHexString(p.tag));
         out.endTag(null, "p");
     }
 
-    private void serializeHost(XmlSerializer out, Host host) throws IOException {
+    private static void serializeHost(XmlSerializer out, Host host) throws IOException {
         out.startTag(null, "h");
-        out.attribute(null, "pkg", host.packageName);
-        out.attribute(null, "id", Integer.toHexString(host.hostId));
+        out.attribute(null, "pkg", host.id.packageName);
+        out.attribute(null, "id", Integer.toHexString(host.id.hostId));
+        out.attribute(null, "tag", Integer.toHexString(host.tag));
         out.endTag(null, "h");
     }
 
-    private void serializeAppWidgetId(XmlSerializer out, AppWidgetId id) throws IOException {
+    private static void serializeAppWidget(XmlSerializer out, Widget widget) throws IOException {
         out.startTag(null, "g");
-        out.attribute(null, "id", Integer.toHexString(id.appWidgetId));
-        out.attribute(null, "rid", Integer.toHexString(id.restoredId));
-        out.attribute(null, "h", Integer.toHexString(id.host.tag));
-        if (id.provider != null) {
-            out.attribute(null, "p", Integer.toHexString(id.provider.tag));
+        out.attribute(null, "id", Integer.toHexString(widget.appWidgetId));
+        out.attribute(null, "rid", Integer.toHexString(widget.restoredId));
+        out.attribute(null, "h", Integer.toHexString(widget.host.tag));
+        if (widget.provider != null) {
+            out.attribute(null, "p", Integer.toHexString(widget.provider.tag));
         }
-        if (id.options != null) {
-            out.attribute(null, "min_width", Integer.toHexString(id.options.getInt(
+        if (widget.options != null) {
+            out.attribute(null, "min_width", Integer.toHexString(widget.options.getInt(
                     AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)));
-            out.attribute(null, "min_height", Integer.toHexString(id.options.getInt(
+            out.attribute(null, "min_height", Integer.toHexString(widget.options.getInt(
                     AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT)));
-            out.attribute(null, "max_width", Integer.toHexString(id.options.getInt(
+            out.attribute(null, "max_width", Integer.toHexString(widget.options.getInt(
                     AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH)));
-            out.attribute(null, "max_height", Integer.toHexString(id.options.getInt(
+            out.attribute(null, "max_height", Integer.toHexString(widget.options.getInt(
                     AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT)));
-            out.attribute(null, "host_category", Integer.toHexString(id.options.getInt(
+            out.attribute(null, "host_category", Integer.toHexString(widget.options.getInt(
                     AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY)));
         }
         out.endTag(null, "g");
     }
 
-    private Bundle parseWidgetIdOptions(XmlPullParser parser) {
-        Bundle options = new Bundle();
-        String minWidthString = parser.getAttributeValue(null, "min_width");
-        if (minWidthString != null) {
-            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH,
-                    Integer.parseInt(minWidthString, 16));
-        }
-        String minHeightString = parser.getAttributeValue(null, "min_height");
-        if (minHeightString != null) {
-            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT,
-                    Integer.parseInt(minHeightString, 16));
-        }
-        String maxWidthString = parser.getAttributeValue(null, "max_width");
-        if (maxWidthString != null) {
-            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH,
-                    Integer.parseInt(maxWidthString, 16));
-        }
-        String maxHeightString = parser.getAttributeValue(null, "max_height");
-        if (maxHeightString != null) {
-            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT,
-                    Integer.parseInt(maxHeightString, 16));
-        }
-        String categoryString = parser.getAttributeValue(null, "host_category");
-        if (categoryString != null) {
-            options.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
-                    Integer.parseInt(categoryString, 16));
-        }
-        return options;
+    @Override
+    public List<String> getWidgetParticipants(int userId) {
+        return mBackupRestoreController.getWidgetParticipants(userId);
     }
 
-    // Does this package either host or provide any active widgets?
-    private boolean packageNeedsWidgetBackupLocked(String packageName) {
-        int N = mAppWidgetIds.size();
-        for (int i = 0; i < N; i++) {
-            AppWidgetId id = mAppWidgetIds.get(i);
-            if (packageName.equals(id.host.packageName)) {
-                // this package is hosting widgets, so it knows widget IDs
-                return true;
-            }
-            Provider p = id.provider;
-            if (p != null && packageName.equals(p.info.provider.getPackageName())) {
-                // someone is hosting this app's widgets, so it knows widget IDs
-                return true;
-            }
-        }
-        return false;
+    @Override
+    public byte[] getWidgetState(String packageName, int userId) {
+        return mBackupRestoreController.getWidgetState(packageName, userId);
     }
 
-    // build the widget-state blob that we save for the app during backup.
-    public byte[] getWidgetState(String backupTarget) {
-        if (!mHasFeature) {
-            return null;
-        }
-
-        ByteArrayOutputStream stream = new ByteArrayOutputStream();
-        synchronized (mAppWidgetIds) {
-            // Preflight: if this app neither hosts nor provides any live widgets
-            // we have no work to do.
-            if (!packageNeedsWidgetBackupLocked(backupTarget)) {
-                return null;
-            }
-
-            try {
-                XmlSerializer out = new FastXmlSerializer();
-                out.setOutput(stream, "utf-8");
-                out.startDocument(null, true);
-                out.startTag(null, "ws");      // widget state
-                out.attribute(null, "version", String.valueOf(WIDGET_STATE_VERSION));
-                out.attribute(null, "pkg", backupTarget);
-
-                // Remember all the providers that are currently hosted or published
-                // by this package: that is, all of the entities related to this app
-                // which will need to be told about id remapping.
-                int N = mInstalledProviders.size();
-                int index = 0;
-                for (int i = 0; i < N; i++) {
-                    Provider p = mInstalledProviders.get(i);
-                    if (p.instances.size() > 0) {
-                        if (backupTarget.equals(p.info.provider.getPackageName())
-                                || p.isHostedBy(backupTarget)) {
-                            serializeProvider(out, p);
-                            p.tag = index++;
-                        }
-                    }
-                }
-
-                N = mHosts.size();
-                index = 0;
-                for (int i = 0; i < N; i++) {
-                    Host host = mHosts.get(i);
-                    if (backupTarget.equals(host.packageName)
-                            || host.hostsPackage(backupTarget)) {
-                        serializeHost(out, host);
-                        host.tag = index++;
-                    }
-                }
-
-                // All widget instances involving this package,
-                // either as host or as provider
-                N = mAppWidgetIds.size();
-                for (int i = 0; i < N; i++) {
-                    AppWidgetId id = mAppWidgetIds.get(i);
-                    if (backupTarget.equals(id.host.packageName)
-                            || (id.provider != null && backupTarget.equals(
-                                    id.provider.info.provider.getPackageName()))) {
-                        serializeAppWidgetId(out, id);
-                    }
-                }
-
-                out.endTag(null, "ws");
-                out.endDocument();
-            } catch (IOException e) {
-                Slog.w(TAG, "Unable to save widget state for " + backupTarget);
-                return null;
-            }
-
-        }
-        return stream.toByteArray();
+    @Override
+    public void restoreStarting(int userId) {
+        mBackupRestoreController.restoreStarting(userId);
     }
 
-    public void restoreStarting() {
-        if (DEBUG_BACKUP) {
-            Slog.i(TAG, "restore starting for user " + mUserId);
-        }
-        synchronized (mRestoredWidgetIds) {
-            // We're starting a new "system" restore operation, so any widget restore
-            // state that we see from here on is intended to replace the current
-            // widget configuration of any/all of the affected apps.
-            mPrunedApps.clear();
-            mUpdatesByProvider.clear();
-            mUpdatesByHost.clear();
-        }
+    @Override
+    public void restoreWidgetState(String packageName, byte[] restoredState, int userId) {
+        mBackupRestoreController.restoreWidgetState(packageName, restoredState, userId);
     }
 
-    // We're restoring widget state for 'pkg', so we start by wiping (a) all widget
-    // instances that are hosted by that app, and (b) all instances in other hosts
-    // for which 'pkg' is the provider.  We assume that we'll be restoring all of
-    // these hosts & providers, so will be reconstructing a correct live state.
-    private void pruneWidgetStateLr(String pkg) {
-        if (!mPrunedApps.contains(pkg)) {
-            if (DEBUG_BACKUP) {
-                Slog.i(TAG, "pruning widget state for restoring package " + pkg);
-            }
-            for (int i = mAppWidgetIds.size() - 1; i >= 0; i--) {
-                AppWidgetId id = mAppWidgetIds.get(i);
-                Provider p = id.provider;
-                if (id.host.packageName.equals(pkg)
-                        || p.info.provider.getPackageName().equals(pkg)) {
-                    // 'pkg' is either the host or the provider for this instances,
-                    // so we tear it down in anticipation of it (possibly) being
-                    // reconstructed due to the restore
-                    p.instances.remove(id);
-
-                    unbindAppWidgetRemoteViewsServicesLocked(id);
-                    mAppWidgetIds.remove(i);
-                }
-            }
-            mPrunedApps.add(pkg);
-        } else {
-            if (DEBUG_BACKUP) {
-                Slog.i(TAG, "already pruned " + pkg + ", continuing normally");
-            }
-        }
+    @Override
+    public void restoreFinished(int userId) {
+        mBackupRestoreController.restoreFinished(userId);
     }
 
-    // Accumulate a list of updates that affect the given provider for a final
-    // coalesced notification broadcast once restore is over.
-    class RestoreUpdateRecord {
-        public int oldId;
-        public int newId;
-        public boolean notified;
-
-        public RestoreUpdateRecord(int theOldId, int theNewId) {
-            oldId = theOldId;
-            newId = theNewId;
-            notified = false;
-        }
-    }
-
-    HashMap<Provider, ArrayList<RestoreUpdateRecord>> mUpdatesByProvider
-            = new HashMap<Provider, ArrayList<RestoreUpdateRecord>>();
-    HashMap<Host, ArrayList<RestoreUpdateRecord>> mUpdatesByHost
-            = new HashMap<Host, ArrayList<RestoreUpdateRecord>>();
-
-    private boolean alreadyStashed(ArrayList<RestoreUpdateRecord> stash,
-            final int oldId, final int newId) {
-        final int N = stash.size();
-        for (int i = 0; i < N; i++) {
-            RestoreUpdateRecord r = stash.get(i);
-            if (r.oldId == oldId && r.newId == newId) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private void stashProviderRestoreUpdateLr(Provider provider, int oldId, int newId) {
-        ArrayList<RestoreUpdateRecord> r = mUpdatesByProvider.get(provider);
-        if (r == null) {
-            r = new ArrayList<RestoreUpdateRecord>();
-            mUpdatesByProvider.put(provider, r);
-        } else {
-            // don't duplicate
-            if (alreadyStashed(r, oldId, newId)) {
-                if (DEBUG_BACKUP) {
-                    Slog.i(TAG, "ID remap " + oldId + " -> " + newId
-                            + " already stashed for " + provider);
-                }
-                return;
-            }
-        }
-        r.add(new RestoreUpdateRecord(oldId, newId));
-    }
-
-    private void stashHostRestoreUpdateLr(Host host, int oldId, int newId) {
-        ArrayList<RestoreUpdateRecord> r = mUpdatesByHost.get(host);
-        if (r == null) {
-            r = new ArrayList<RestoreUpdateRecord>();
-            mUpdatesByHost.put(host, r);
-        } else {
-            if (alreadyStashed(r, oldId, newId)) {
-                if (DEBUG_BACKUP) {
-                    Slog.i(TAG, "ID remap " + oldId + " -> " + newId
-                            + " already stashed for " + host);
-                }
-                return;
-            }
-        }
-        r.add(new RestoreUpdateRecord(oldId, newId));
-    }
-
-    public void restoreWidgetState(String packageName, byte[] restoredState) {
-        if (!mHasFeature) {
-            return;
-        }
-
-        if (DEBUG_BACKUP) {
-            Slog.i(TAG, "Restoring widget state for " + packageName);
-        }
-
-        ByteArrayInputStream stream = new ByteArrayInputStream(restoredState);
-        try {
-            // Providers mentioned in the widget dataset by ordinal
-            ArrayList<Provider> restoredProviders = new ArrayList<Provider>();
-
-            // Hosts mentioned in the widget dataset by ordinal
-            ArrayList<Host> restoredHosts = new ArrayList<Host>();
-
-            //HashSet<String> toNotify = new HashSet<String>();
-
-            XmlPullParser parser = Xml.newPullParser();
-            parser.setInput(stream, null);
-
-            synchronized (mAppWidgetIds) {
-                synchronized (mRestoredWidgetIds) {
-                    int type;
-                    do {
-                        type = parser.next();
-                        if (type == XmlPullParser.START_TAG) {
-                            final String tag = parser.getName();
-                            if ("ws".equals(tag)) {
-                                String v = parser.getAttributeValue(null, "version");
-                                String pkg = parser.getAttributeValue(null, "pkg");
-
-                                // TODO: fix up w.r.t. canonical vs current package names
-                                if (!packageName.equals(pkg)) {
-                                    Slog.w(TAG, "Package mismatch in ws");
-                                    return;
-                                }
-
-                                int version = Integer.parseInt(v);
-                                if (version > WIDGET_STATE_VERSION) {
-                                    Slog.w(TAG, "Unable to process state version " + version);
-                                    return;
-                                }
-                            } else if ("p".equals(tag)) {
-                                String pkg = parser.getAttributeValue(null, "pkg");
-                                String cl = parser.getAttributeValue(null, "cl");
-
-                                // hostedProviders index will match 'p' attribute in widget's
-                                // entry in the xml file being restored
-                                // If there's no live entry for this provider, add an inactive one
-                                // so that widget IDs referring to them can be properly allocated
-                                final ComponentName cn = new ComponentName(pkg, cl);
-                                Provider p = lookupProviderLocked(cn, mInstalledProviders);
-                                if (p == null) {
-                                    p = new Provider();
-                                    p.info = new AppWidgetProviderInfo();
-                                    p.info.provider = cn;
-                                    p.zombie = true;
-                                    mInstalledProviders.add(p);
-                                }
-                                if (DEBUG_BACKUP) {
-                                    Slog.i(TAG, "   provider " + cn);
-                                }
-                                restoredProviders.add(p);
-                            } else if ("h".equals(tag)) {
-                                // The host app may not yet exist on the device.  If it's here we
-                                // just use the existing Host entry, otherwise we create a
-                                // placeholder whose uid will be fixed up at PACKAGE_ADDED time.
-                                String pkg = parser.getAttributeValue(null, "pkg");
-                                int uid;
-                                try {
-                                    uid = getUidForPackage(pkg);
-                                } catch (NameNotFoundException e) {
-                                    uid = -1;
-                                }
-                                int hostId = Integer.parseInt(
-                                        parser.getAttributeValue(null, "id"), 16);
-                                Host h = lookupOrAddHostLocked(uid, pkg, hostId);
-                                if (DEBUG_BACKUP) {
-                                    Slog.i(TAG, "   host[" + restoredHosts.size()
-                                            + "]: {" + h.packageName + ":" + h.hostId + "}");
-                                }
-                                restoredHosts.add(h);
-                            } else if ("g".equals(tag)) {
-                                int restoredId = Integer.parseInt(
-                                        parser.getAttributeValue(null, "id"), 16);
-                                int hostIndex = Integer.parseInt(
-                                        parser.getAttributeValue(null, "h"), 16);
-                                Host host = restoredHosts.get(hostIndex);
-                                Provider p = null;
-                                String prov = parser.getAttributeValue(null, "p");
-                                if (prov != null) {
-                                    // could have been null if the app had allocated an id
-                                    // but not yet established a binding under that id
-                                    int which = Integer.parseInt(prov, 16);
-                                    p = restoredProviders.get(which);
-                                }
-
-                                // We'll be restoring widget state for both the host and
-                                // provider sides of this widget ID, so make sure we are
-                                // beginning from a clean slate on both fronts.
-                                pruneWidgetStateLr(host.packageName);
-                                if (p != null) {
-                                    pruneWidgetStateLr(p.info.provider.getPackageName());
-                                }
-
-                                // Have we heard about this ancestral widget instance before?
-                                AppWidgetId id = findRestoredWidgetLocked(restoredId, host, p);
-                                if (id == null) {
-                                    id = new AppWidgetId();
-                                    id.appWidgetId = mNextAppWidgetId++;
-                                    id.restoredId = restoredId;
-                                    id.options = parseWidgetIdOptions(parser);
-                                    id.host = host;
-                                    id.host.instances.add(id);
-                                    id.provider = p;
-                                    if (id.provider != null) {
-                                        id.provider.instances.add(id);
-                                    }
-                                    if (DEBUG_BACKUP) {
-                                        Slog.i(TAG, "New restored id " + restoredId
-                                                + " now " + id);
-                                    }
-                                    mAppWidgetIds.add(id);
-                                }
-                                if (id.provider.info != null) {
-                                    stashProviderRestoreUpdateLr(id.provider,
-                                            restoredId, id.appWidgetId);
-                                } else {
-                                    Slog.w(TAG, "Missing provider for restored widget " + id);
-                                }
-                                stashHostRestoreUpdateLr(id.host, restoredId, id.appWidgetId);
-
-                                if (DEBUG_BACKUP) {
-                                    Slog.i(TAG, "   instance: " + restoredId
-                                            + " -> " + id.appWidgetId
-                                            + " :: p=" + id.provider);
-                                }
-                            }
-                        }
-                    } while (type != XmlPullParser.END_DOCUMENT);
-
-                    // We've updated our own bookkeeping.  We'll need to notify the hosts and
-                    // providers about the changes, but we can't do that yet because the restore
-                    // target is not necessarily fully live at this moment.  Set aside the
-                    // information for now; the backup manager will call us once more at the
-                    // end of the process when all of the targets are in a known state, and we
-                    // will update at that point.
-                }
-            }
-        } catch (XmlPullParserException e) {
-            Slog.w(TAG, "Unable to restore widget state for " + packageName);
-        } catch (IOException e) {
-            Slog.w(TAG, "Unable to restore widget state for " + packageName);
-        } finally {
-            saveStateAsync();
-        }
-    }
-
-    // Called once following the conclusion of a restore operation.  This is when we
-    // send out updates to apps involved in widget-state restore telling them about
-    // the new widget ID space.
-    public void restoreFinished() {
-        if (DEBUG_BACKUP) {
-            Slog.i(TAG, "restoreFinished for " + mUserId);
-        }
-
-        final UserHandle userHandle = new UserHandle(mUserId);
-        synchronized (mRestoredWidgetIds) {
-            // Build the providers' broadcasts and send them off
-            Set<Entry<Provider, ArrayList<RestoreUpdateRecord>>> providerEntries
-                    = mUpdatesByProvider.entrySet();
-            for (Entry<Provider, ArrayList<RestoreUpdateRecord>> e : providerEntries) {
-                // For each provider there's a list of affected IDs
-                Provider provider = e.getKey();
-                ArrayList<RestoreUpdateRecord> updates = e.getValue();
-                final int pending = countPendingUpdates(updates);
-                if (DEBUG_BACKUP) {
-                    Slog.i(TAG, "Provider " + provider + " pending: " + pending);
-                }
-                if (pending > 0) {
-                    int[] oldIds = new int[pending];
-                    int[] newIds = new int[pending];
-                    final int N = updates.size();
-                    int nextPending = 0;
-                    for (int i = 0; i < N; i++) {
-                        RestoreUpdateRecord r = updates.get(i);
-                        if (!r.notified) {
-                            r.notified = true;
-                            oldIds[nextPending] = r.oldId;
-                            newIds[nextPending] = r.newId;
-                            nextPending++;
-                            if (DEBUG_BACKUP) {
-                                Slog.i(TAG, "   " + r.oldId + " => " + r.newId);
-                            }
-                        }
-                    }
-                    sendWidgetRestoreBroadcast(AppWidgetManager.ACTION_APPWIDGET_RESTORED,
-                            provider, null, oldIds, newIds, userHandle);
-                }
-            }
-
-            // same thing per host
-            Set<Entry<Host, ArrayList<RestoreUpdateRecord>>> hostEntries
-                    = mUpdatesByHost.entrySet();
-            for (Entry<Host, ArrayList<RestoreUpdateRecord>> e : hostEntries) {
-                Host host = e.getKey();
-                if (host.uid > 0) {
-                    ArrayList<RestoreUpdateRecord> updates = e.getValue();
-                    final int pending = countPendingUpdates(updates);
-                    if (DEBUG_BACKUP) {
-                        Slog.i(TAG, "Host " + host + " pending: " + pending);
-                    }
-                    if (pending > 0) {
-                        int[] oldIds = new int[pending];
-                        int[] newIds = new int[pending];
-                        final int N = updates.size();
-                        int nextPending = 0;
-                        for (int i = 0; i < N; i++) {
-                            RestoreUpdateRecord r = updates.get(i);
-                            if (!r.notified) {
-                                r.notified = true;
-                                oldIds[nextPending] = r.oldId;
-                                newIds[nextPending] = r.newId;
-                                nextPending++;
-                                if (DEBUG_BACKUP) {
-                                    Slog.i(TAG, "   " + r.oldId + " => " + r.newId);
-                                }
-                            }
-                        }
-                        sendWidgetRestoreBroadcast(AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED,
-                                null, host, oldIds, newIds, userHandle);
-                    }
-                }
-            }
-        }
-    }
-
-    private int countPendingUpdates(ArrayList<RestoreUpdateRecord> updates) {
-        int pending = 0;
-        final int N = updates.size();
-        for (int i = 0; i < N; i++) {
-            RestoreUpdateRecord r = updates.get(i);
-            if (!r.notified) {
-                pending++;
-            }
-        }
-        return pending;
-    }
-
-    void sendWidgetRestoreBroadcast(String action, Provider provider, Host host,
-            int[] oldIds, int[] newIds, UserHandle userHandle) {
-        Intent intent = new Intent(action);
-        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS, oldIds);
-        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, newIds);
-        if (provider != null) {
-            intent.setComponent(provider.info.provider);
-            mContext.sendBroadcastAsUser(intent, userHandle);
-        }
-        if (host != null) {
-            intent.setComponent(null);
-            intent.setPackage(host.packageName);
-            intent.putExtra(AppWidgetManager.EXTRA_HOST_ID, host.hostId);
-            mContext.sendBroadcastAsUser(intent, userHandle);
-        }
-    }
-
-    private Provider parseProviderInfoXml(ComponentName component, ResolveInfo ri) {
-        Provider p = null;
+    @SuppressWarnings("deprecation")
+    private Provider parseProviderInfoXml(ProviderId providerId, ResolveInfo ri) {
+        Provider provider = null;
 
         ActivityInfo activityInfo = ri.activityInfo;
         XmlResourceParser parser = null;
@@ -2165,7 +2107,7 @@
                     AppWidgetManager.META_DATA_APPWIDGET_PROVIDER);
             if (parser == null) {
                 Slog.w(TAG, "No " + AppWidgetManager.META_DATA_APPWIDGET_PROVIDER
-                        + " meta-data for " + "AppWidget provider '" + component + '\'');
+                        + " meta-data for " + "AppWidget provider '" + providerId + '\'');
                 return null;
             }
 
@@ -2180,19 +2122,28 @@
             String nodeName = parser.getName();
             if (!"appwidget-provider".equals(nodeName)) {
                 Slog.w(TAG, "Meta-data does not start with appwidget-provider tag for"
-                        + " AppWidget provider '" + component + '\'');
+                        + " AppWidget provider " + providerId.componentName
+                        + " for user " + providerId.uid);
                 return null;
             }
 
-            p = new Provider();
-            AppWidgetProviderInfo info = p.info = new AppWidgetProviderInfo();
-            info.provider = component;
-            p.uid = activityInfo.applicationInfo.uid;
+            provider = new Provider();
+            provider.id = providerId;
+            AppWidgetProviderInfo info = provider.info = new AppWidgetProviderInfo();
+            info.provider = providerId.componentName;
+            info.providerInfo = activityInfo;
 
-            Resources res = mContext.getPackageManager()
-                    .getResourcesForApplicationAsUser(activityInfo.packageName, mUserId);
+            final Resources resources;
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                resources = mContext.getPackageManager()
+                        .getResourcesForApplicationAsUser(activityInfo.packageName,
+                                UserHandle.getUserId(providerId.uid));
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
 
-            TypedArray sa = res.obtainAttributes(attrs,
+            TypedArray sa = resources.obtainAttributes(attrs,
                     com.android.internal.R.styleable.AppWidgetProviderInfo);
 
             // These dimensions has to be resolved in the application's context.
@@ -2215,10 +2166,12 @@
                     com.android.internal.R.styleable.AppWidgetProviderInfo_initialLayout, 0);
             info.initialKeyguardLayout = sa.getResourceId(com.android.internal.R.styleable.
                     AppWidgetProviderInfo_initialKeyguardLayout, 0);
+
             String className = sa
                     .getString(com.android.internal.R.styleable.AppWidgetProviderInfo_configure);
             if (className != null) {
-                info.configure = new ComponentName(component.getPackageName(), className);
+                info.configure = new ComponentName(providerId.componentName.getPackageName(),
+                        className);
             }
             info.label = activityInfo.loadLabel(mContext.getPackageManager()).toString();
             info.icon = ri.getIconResource();
@@ -2234,111 +2187,224 @@
                     AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN);
 
             sa.recycle();
-        } catch (Exception e) {
+        } catch (IOException | PackageManager.NameNotFoundException | XmlPullParserException e) {
             // Ok to catch Exception here, because anything going wrong because
             // of what a client process passes to us should not be fatal for the
             // system process.
-            Slog.w(TAG, "XML parsing failed for AppWidget provider '" + component + '\'', e);
+            Slog.w(TAG, "XML parsing failed for AppWidget provider "
+                    + providerId.componentName + " for user " + providerId.uid, e);
             return null;
         } finally {
-            if (parser != null)
+            if (parser != null) {
                 parser.close();
+            }
         }
-        return p;
+        return provider;
     }
 
-    int getUidForPackage(String packageName) throws PackageManager.NameNotFoundException {
+    private int getUidForPackage(String packageName, int userId) {
         PackageInfo pkgInfo = null;
+
+        final long identity = Binder.clearCallingIdentity();
         try {
-            pkgInfo = mPm.getPackageInfo(packageName, 0, mUserId);
+            pkgInfo = mPackageManager.getPackageInfo(packageName, 0, userId);
         } catch (RemoteException re) {
             // Shouldn't happen, local call
+        } finally {
+            Binder.restoreCallingIdentity(identity);
         }
+
         if (pkgInfo == null || pkgInfo.applicationInfo == null) {
-            throw new PackageManager.NameNotFoundException();
+            return -1;
         }
+
         return pkgInfo.applicationInfo.uid;
     }
 
-    int enforceSystemOrCallingUid(String packageName) throws IllegalArgumentException {
-        int callingUid = Binder.getCallingUid();
-        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID || callingUid == 0) {
-            return callingUid;
+    private ActivityInfo getProviderInfo(ComponentName componentName, int userId) {
+        Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
+        intent.setComponent(componentName);
+
+        List<ResolveInfo> receivers = queryIntentReceivers(intent, userId);
+        // We are setting component, so there is only one or none.
+        if (!receivers.isEmpty()) {
+            return receivers.get(0).activityInfo;
         }
-        return enforceCallingUid(packageName);
+
+        return null;
     }
 
-    int enforceCallingUid(String packageName) throws IllegalArgumentException {
-        int callingUid = Binder.getCallingUid();
-        int packageUid;
+    private List<ResolveInfo> queryIntentReceivers(Intent intent, int userId) {
+        final long identity = Binder.clearCallingIdentity();
         try {
-            packageUid = getUidForPackage(packageName);
-        } catch (PackageManager.NameNotFoundException ex) {
-            throw new IllegalArgumentException("packageName and uid don't match packageName="
-                    + packageName);
+            return mPackageManager.queryIntentReceivers(intent,
+                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                    PackageManager.GET_META_DATA, userId);
+        } catch (RemoteException re) {
+            return Collections.emptyList();
+        } finally {
+            Binder.restoreCallingIdentity(identity);
         }
-        if (!UserHandle.isSameApp(callingUid, packageUid)) {
-            throw new IllegalArgumentException("packageName and uid don't match packageName="
-                    + packageName);
-        }
-        return callingUid;
     }
 
-    void sendInitialBroadcasts() {
-        synchronized (mAppWidgetIds) {
-            ensureStateLoadedLocked();
-            final int N = mInstalledProviders.size();
+    private void onUserStarted(int userId) {
+        synchronized (mLock) {
+            ensureGroupStateLoadedLocked(userId);
+
+            final int N = mProviders.size();
             for (int i = 0; i < N; i++) {
-                Provider p = mInstalledProviders.get(i);
-                if (p.instances.size() > 0) {
-                    sendEnableIntentLocked(p);
-                    int[] appWidgetIds = getAppWidgetIds(p);
-                    sendUpdateIntentLocked(p, appWidgetIds);
-                    registerForBroadcastsLocked(p, appWidgetIds);
+                Provider provider = mProviders.get(i);
+
+                // Send broadcast only to the providers of the user.
+                if (provider.getUserId() != userId) {
+                    continue;
+                }
+
+                if (provider.widgets.size() > 0) {
+                    sendEnableIntentLocked(provider);
+                    int[] appWidgetIds = getWidgetIds(provider.widgets);
+                    sendUpdateIntentLocked(provider, appWidgetIds);
+                    registerForBroadcastsLocked(provider, appWidgetIds);
                 }
             }
         }
     }
 
     // only call from initialization -- it assumes that the data structures are all empty
-    void loadStateLocked() {
-        AtomicFile file = savedStateFile();
-        try {
-            FileInputStream stream = file.openRead();
-            readStateFromFileLocked(stream);
+    private void loadGroupStateLocked(int[] profileIds) {
+        // We can bind the widgets to host and providers only after
+        // reading the host and providers for all users since a widget
+        // can have a host and a provider in different users.
+        List<LoadedWidgetState> loadedWidgets = new ArrayList<>();
 
-            if (stream != null) {
-                try {
-                    stream.close();
-                } catch (IOException e) {
-                    Slog.w(TAG, "Failed to close state FileInputStream " + e);
+        int version = 0;
+
+        final int profileIdCount = profileIds.length;
+        for (int i = 0; i < profileIdCount; i++) {
+            final int profileId = profileIds[i];
+
+            // No file written for this user - nothing to do.
+            AtomicFile file = getSavedStateFile(profileId);
+            try {
+                FileInputStream stream = file.openRead();
+                version = readProfileStateFromFileLocked(stream, profileId, loadedWidgets);
+                IoUtils.closeQuietly(stream);
+            } catch (FileNotFoundException e) {
+                Slog.w(TAG, "Failed to read state: " + e);
+            }
+        }
+
+        if (version >= 0) {
+            // Hooke'm up...
+            bindLoadedWidgets(loadedWidgets);
+
+            // upgrade the database if needed
+            performUpgradeLocked(version);
+        } else {
+            // failed reading, clean up
+            Slog.w(TAG, "Failed to read state, clearing widgets and hosts.");
+            mWidgets.clear();
+            mHosts.clear();
+            final int N = mProviders.size();
+            for (int i = 0; i < N; i++) {
+                mProviders.get(i).widgets.clear();
+            }
+        }
+    }
+
+    private void bindLoadedWidgets(List<LoadedWidgetState> loadedWidgets) {
+        final int loadedWidgetCount = loadedWidgets.size();
+        for (int i = loadedWidgetCount - 1; i >= 0; i--) {
+            LoadedWidgetState loadedWidget = loadedWidgets.remove(i);
+            Widget widget = loadedWidget.widget;
+
+            widget.provider = findProviderByTag(loadedWidget.providerTag);
+            if (widget.provider == null) {
+                // This provider is gone. We just let the host figure out
+                // that this happened when it fails to load it.
+                continue;
+            }
+
+            widget.host = findHostByTag(loadedWidget.hostTag);
+            if (widget.host == null) {
+                // This host is gone.
+                continue;
+            }
+
+            widget.provider.widgets.add(widget);
+            widget.host.widgets.add(widget);
+            mWidgets.add(widget);
+        }
+    }
+
+    private Provider findProviderByTag(int tag) {
+        if (tag < 0) {
+            return null;
+        }
+        final int providerCount = mProviders.size();
+        for (int i = 0; i < providerCount; i++) {
+            Provider provider = mProviders.get(i);
+            if (provider.tag == tag) {
+                return provider;
+            }
+        }
+        return null;
+    }
+
+    private Host findHostByTag(int tag) {
+        if (tag < 0) {
+            return null;
+        }
+        final int hostCount = mHosts.size();
+        for (int i = 0; i < hostCount; i++) {
+            Host host = mHosts.get(i);
+            if (host.tag == tag) {
+                return host;
+            }
+        }
+        return null;
+    }
+
+    private void saveStateLocked(int userId) {
+        tagProvidersAndHosts();
+
+        final int[] profileIds = mSecurityPolicy.getEnabledGroupProfileIds(userId);
+
+        final int profileCount = profileIds.length;
+        for (int i = 0; i < profileCount; i++) {
+            final int profileId = profileIds[i];
+
+            AtomicFile file = getSavedStateFile(profileId);
+            FileOutputStream stream;
+            try {
+                stream = file.startWrite();
+                if (writeProfileStateToFileLocked(stream, profileId)) {
+                    file.finishWrite(stream);
+                } else {
+                    file.failWrite(stream);
+                    Slog.w(TAG, "Failed to save state, restoring backup.");
                 }
+            } catch (IOException e) {
+                Slog.w(TAG, "Failed open state file for write: " + e);
             }
-        } catch (FileNotFoundException e) {
-            Slog.w(TAG, "Failed to read state: " + e);
         }
     }
 
-    void saveStateLocked() {
-        if (!mHasFeature) {
-            return;
+    private void tagProvidersAndHosts() {
+        final int providerCount = mProviders.size();
+        for (int i = 0; i < providerCount; i++) {
+            Provider provider = mProviders.get(i);
+            provider.tag = i;
         }
-        AtomicFile file = savedStateFile();
-        FileOutputStream stream;
-        try {
-            stream = file.startWrite();
-            if (writeStateToFileLocked(stream)) {
-                file.finishWrite(stream);
-            } else {
-                file.failWrite(stream);
-                Slog.w(TAG, "Failed to save state, restoring backup.");
-            }
-        } catch (IOException e) {
-            Slog.w(TAG, "Failed open state file for write: " + e);
+
+        final int hostCount = mHosts.size();
+        for (int i = 0; i < hostCount; i++) {
+            Host host = mHosts.get(i);
+            host.tag = i;
         }
     }
 
-    boolean writeStateToFileLocked(FileOutputStream stream) {
+    private boolean writeProfileStateToFileLocked(FileOutputStream stream, int userId) {
         int N;
 
         try {
@@ -2347,39 +2413,52 @@
             out.startDocument(null, true);
             out.startTag(null, "gs");
             out.attribute(null, "version", String.valueOf(CURRENT_VERSION));
-            int providerIndex = 0;
-            N = mInstalledProviders.size();
+
+            N = mProviders.size();
             for (int i = 0; i < N; i++) {
-                Provider p = mInstalledProviders.get(i);
-                if (p.instances.size() > 0) {
-                    serializeProvider(out, p);
-                    p.tag = providerIndex;
-                    providerIndex++;
+                Provider provider = mProviders.get(i);
+                // Save only providers for the user.
+                if (provider.getUserId() != userId) {
+                    continue;
+                }
+                if (provider.widgets.size() > 0) {
+                    serializeProvider(out, provider);
                 }
             }
 
             N = mHosts.size();
             for (int i = 0; i < N; i++) {
                 Host host = mHosts.get(i);
+                // Save only hosts for the user.
+                if (host.getUserId() != userId) {
+                    continue;
+                }
                 serializeHost(out, host);
-                host.tag = i;
             }
 
-            N = mAppWidgetIds.size();
+            N = mWidgets.size();
             for (int i = 0; i < N; i++) {
-                AppWidgetId id = mAppWidgetIds.get(i);
-                serializeAppWidgetId(out, id);
+                Widget widget = mWidgets.get(i);
+                // Save only widgets hosted by the user.
+                if (widget.host.getUserId() != userId) {
+                    continue;
+                }
+                serializeAppWidget(out, widget);
             }
 
-            Iterator<String> it = mPackagesWithBindWidgetPermission.iterator();
+            Iterator<Pair<Integer, String>> it = mPackagesWithBindWidgetPermission.iterator();
             while (it.hasNext()) {
+                Pair<Integer, String> binding = it.next();
+                // Save only white listings for the user.
+                if (binding.first != userId) {
+                    continue;
+                }
                 out.startTag(null, "b");
-                out.attribute(null, "packageName", it.next());
+                out.attribute(null, "packageName", binding.second);
                 out.endTag(null, "b");
             }
 
             out.endTag(null, "gs");
-
             out.endDocument();
             return true;
         } catch (IOException e) {
@@ -2388,17 +2467,16 @@
         }
     }
 
-    @SuppressWarnings("unused")
-    void readStateFromFileLocked(FileInputStream stream) {
-        boolean success = false;
-        int version = 0;
+    private int readProfileStateFromFileLocked(FileInputStream stream, int userId,
+            List<LoadedWidgetState> outLoadedWidgets) {
+        int version = -1;
         try {
             XmlPullParser parser = Xml.newPullParser();
             parser.setInput(stream, null);
 
+            int legacyProviderIndex = -1;
+            int legacyHostIndex = -1;
             int type;
-            int providerIndex = 0;
-            HashMap<Integer, Provider> loadedProviders = new HashMap<Integer, Provider>();
             do {
                 type = parser.next();
                 if (type == XmlPullParser.START_TAG) {
@@ -2411,67 +2489,89 @@
                             version = 0;
                         }
                     } else if ("p".equals(tag)) {
+                        legacyProviderIndex++;
                         // TODO: do we need to check that this package has the same signature
                         // as before?
                         String pkg = parser.getAttributeValue(null, "pkg");
                         String cl = parser.getAttributeValue(null, "cl");
 
-                        final IPackageManager packageManager = AppGlobals.getPackageManager();
-                        try {
-                            packageManager.getReceiverInfo(new ComponentName(pkg, cl), 0, mUserId);
-                        } catch (RemoteException e) {
-                            String[] pkgs = mContext.getPackageManager()
-                                    .currentToCanonicalPackageNames(new String[] { pkg });
-                            pkg = pkgs[0];
+                        pkg = getCanonicalPackageName(pkg, cl, userId);
+                        if (pkg == null) {
+                            continue;
                         }
 
-                        Provider p = lookupProviderLocked(new ComponentName(pkg, cl));
-                        if (p == null && mSafeMode) {
+                        final int uid = getUidForPackage(pkg, userId);
+                        if (uid < 0) {
+                            continue;
+                        }
+
+                        ComponentName componentName = new ComponentName(pkg, cl);
+
+                        ActivityInfo providerInfo = getProviderInfo(componentName, userId);
+                        if (providerInfo == null) {
+                            continue;
+                        }
+
+                        ProviderId providerId = new ProviderId(uid, componentName);
+                        Provider provider = lookupProviderLocked(providerId);
+
+                        if (provider == null && mSafeMode) {
                             // if we're in safe mode, make a temporary one
-                            p = new Provider();
-                            p.info = new AppWidgetProviderInfo();
-                            p.info.provider = new ComponentName(pkg, cl);
-                            p.zombie = true;
-                            mInstalledProviders.add(p);
+                            provider = new Provider();
+                            provider.info = new AppWidgetProviderInfo();
+                            provider.info.provider = providerId.componentName;
+                            provider.info.providerInfo = providerInfo;
+                            provider.zombie = true;
+                            provider.id = providerId;
+                            mProviders.add(provider);
                         }
-                        if (p != null) {
-                            // if it wasn't uninstalled or something
-                            loadedProviders.put(providerIndex, p);
-                        }
-                        providerIndex++;
-                    } else if ("h".equals(tag)) {
-                        Host host = new Host();
 
+                        String tagAttribute = parser.getAttributeValue(null, "tag");
+                        final int providerTag = !TextUtils.isEmpty(tagAttribute)
+                                ? Integer.parseInt(tagAttribute, 16) : legacyProviderIndex;
+                        provider.tag = providerTag;
+                    } else if ("h".equals(tag)) {
+                        legacyHostIndex++;
+                        Host host = new Host();
                         // TODO: do we need to check that this package has the same signature
                         // as before?
-                        host.packageName = parser.getAttributeValue(null, "pkg");
-                        try {
-                            host.uid = getUidForPackage(host.packageName);
-                        } catch (PackageManager.NameNotFoundException ex) {
+                        String pkg = parser.getAttributeValue(null, "pkg");
+
+                        final int uid = getUidForPackage(pkg, userId);
+                        if (uid < 0) {
                             host.zombie = true;
                         }
+
                         if (!host.zombie || mSafeMode) {
                             // In safe mode, we don't discard the hosts we don't recognize
                             // so that they're not pruned from our list. Otherwise, we do.
-                            host.hostId = Integer
-                                    .parseInt(parser.getAttributeValue(null, "id"), 16);
+                            final int hostId = Integer.parseInt(parser.getAttributeValue(
+                                    null, "id"), 16);
+
+                            String tagAttribute = parser.getAttributeValue(null, "tag");
+                            final int hostTag = !TextUtils.isEmpty(tagAttribute)
+                                    ? Integer.parseInt(tagAttribute, 16) : legacyHostIndex;
+
+                            host.tag = hostTag;
+                            host.id = new HostId(uid, hostId, pkg);
                             mHosts.add(host);
                         }
                     } else if ("b".equals(tag)) {
                         String packageName = parser.getAttributeValue(null, "packageName");
-                        if (packageName != null) {
-                            mPackagesWithBindWidgetPermission.add(packageName);
+                        final int uid = getUidForPackage(packageName, userId);
+                        if (uid >= 0) {
+                            Pair<Integer, String> packageId = Pair.create(userId, packageName);
+                            mPackagesWithBindWidgetPermission.add(packageId);
                         }
                     } else if ("g".equals(tag)) {
-                        AppWidgetId id = new AppWidgetId();
-                        id.appWidgetId = Integer.parseInt(parser.getAttributeValue(null, "id"), 16);
-                        if (id.appWidgetId >= mNextAppWidgetId) {
-                            mNextAppWidgetId = id.appWidgetId + 1;
-                        }
+                        Widget widget = new Widget();
+                        widget.appWidgetId = Integer.parseInt(parser.getAttributeValue(
+                                null, "id"), 16);
+                        setMinAppWidgetIdLocked(userId, widget.appWidgetId + 1);
 
                         // restored ID is allowed to be absent
                         String restoredIdString = parser.getAttributeValue(null, "rid");
-                        id.restoredId = (restoredIdString == null) ? 0
+                        widget.restoredId = (restoredIdString == null) ? 0
                                 : Integer.parseInt(restoredIdString, 16);
 
                         Bundle options = new Bundle();
@@ -2500,92 +2600,57 @@
                             options.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
                                     Integer.parseInt(categoryString, 16));
                         }
-                        id.options = options;
+                        widget.options = options;
 
+                        final int hostTag = Integer.parseInt(parser.getAttributeValue(
+                                null, "h"), 16);
                         String providerString = parser.getAttributeValue(null, "p");
-                        if (providerString != null) {
-                            // there's no provider if it hasn't been bound yet.
-                            // maybe we don't have to save this, but it brings the system
-                            // to the state it was in.
-                            int pIndex = Integer.parseInt(providerString, 16);
-                            id.provider = loadedProviders.get(pIndex);
-                            if (false) {
-                                Slog.d(TAG, "bound appWidgetId=" + id.appWidgetId + " to provider "
-                                        + pIndex + " which is " + id.provider);
-                            }
-                            if (id.provider == null) {
-                                // This provider is gone. We just let the host figure out
-                                // that this happened when it fails to load it.
-                                continue;
-                            }
-                        }
+                        final int providerTag = (providerString != null) ? Integer.parseInt(
+                                parser.getAttributeValue(null, "p"), 16) : TAG_UNDEFINED;
 
-                        int hIndex = Integer.parseInt(parser.getAttributeValue(null, "h"), 16);
-                        id.host = mHosts.get(hIndex);
-                        if (id.host == null) {
-                            // This host is gone.
-                            continue;
-                        }
-
-                        if (id.provider != null) {
-                            id.provider.instances.add(id);
-                        }
-                        id.host.instances.add(id);
-                        mAppWidgetIds.add(id);
+                        // We can match widgets with hosts and providers only after hosts
+                        // and providers for all users have been loaded since the widget
+                        // host and provider can be in different user profiles.
+                        LoadedWidgetState loadedWidgets = new LoadedWidgetState(widget,
+                                hostTag, providerTag);
+                        outLoadedWidgets.add(loadedWidgets);
                     }
                 }
             } while (type != XmlPullParser.END_DOCUMENT);
-            success = true;
-        } catch (NullPointerException e) {
+        } catch (NullPointerException
+                | NumberFormatException
+                | XmlPullParserException
+                | IOException
+                | IndexOutOfBoundsException e) {
             Slog.w(TAG, "failed parsing " + e);
-        } catch (NumberFormatException e) {
-            Slog.w(TAG, "failed parsing " + e);
-        } catch (XmlPullParserException e) {
-            Slog.w(TAG, "failed parsing " + e);
-        } catch (IOException e) {
-            Slog.w(TAG, "failed parsing " + e);
-        } catch (IndexOutOfBoundsException e) {
-            Slog.w(TAG, "failed parsing " + e);
+            return -1;
         }
 
-        if (success) {
-            // delete any hosts that didn't manage to get connected (should happen)
-            // if it matters, they'll be reconnected.
-            for (int i = mHosts.size() - 1; i >= 0; i--) {
-                pruneHostLocked(mHosts.get(i));
-            }
-            // upgrade the database if needed
-            performUpgrade(version);
-        } else {
-            // failed reading, clean up
-            Slog.w(TAG, "Failed to read state, clearing widgets and hosts.");
-
-            mAppWidgetIds.clear();
-            mHosts.clear();
-            final int N = mInstalledProviders.size();
-            for (int i = 0; i < N; i++) {
-                mInstalledProviders.get(i).instances.clear();
-            }
-        }
+        return version;
     }
 
-    private void performUpgrade(int fromVersion) {
+    private void performUpgradeLocked(int fromVersion) {
         if (fromVersion < CURRENT_VERSION) {
-            Slog.v(TAG, "Upgrading widget database from " + fromVersion + " to " + CURRENT_VERSION
-                    + " for user " + mUserId);
+            Slog.v(TAG, "Upgrading widget database from " + fromVersion + " to "
+                    + CURRENT_VERSION);
         }
 
         int version = fromVersion;
 
         // Update 1: keyguard moved from package "android" to "com.android.keyguard"
         if (version == 0) {
-            for (int i = 0; i < mHosts.size(); i++) {
-                Host host = mHosts.get(i);
-                if (host != null && "android".equals(host.packageName)
-                        && host.hostId == KEYGUARD_HOST_ID) {
-                    host.packageName = KEYGUARD_HOST_PACKAGE;
+            HostId oldHostId = new HostId(Process.myUid(),
+                    KEYGUARD_HOST_ID, OLD_KEYGUARD_HOST_PACKAGE);
+
+            Host host = lookupHostLocked(oldHostId);
+            if (host != null) {
+                final int uid = getUidForPackage(NEW_KEYGUARD_HOST_PACKAGE,
+                        UserHandle.USER_OWNER);
+                if (uid >= 0) {
+                    host.id = new HostId(uid, KEYGUARD_HOST_ID, NEW_KEYGUARD_HOST_PACKAGE);
                 }
             }
+
             version = 1;
         }
 
@@ -2594,19 +2659,19 @@
         }
     }
 
-    static File getSettingsFile(int userId) {
-        return new File(Environment.getUserSystemDirectory(userId), SETTINGS_FILENAME);
+    private static File getStateFile(int userId) {
+        return new File(Environment.getUserSystemDirectory(userId), STATE_FILENAME);
     }
 
-    AtomicFile savedStateFile() {
-        File dir = Environment.getUserSystemDirectory(mUserId);
-        File settingsFile = getSettingsFile(mUserId);
-        if (!settingsFile.exists() && mUserId == 0) {
+    private static AtomicFile getSavedStateFile(int userId) {
+        File dir = Environment.getUserSystemDirectory(userId);
+        File settingsFile = getStateFile(userId);
+        if (!settingsFile.exists() && userId == UserHandle.USER_OWNER) {
             if (!dir.exists()) {
                 dir.mkdirs();
             }
             // Migrate old data
-            File oldFile = new File("/data/system/" + SETTINGS_FILENAME);
+            File oldFile = new File("/data/system/" + STATE_FILENAME);
             // Method doesn't throw an exception on failure. Ignore any errors
             // in moving the file (like non-existence)
             oldFile.renameTo(settingsFile);
@@ -2614,45 +2679,70 @@
         return new AtomicFile(settingsFile);
     }
 
-    void onUserStopping() {
-        // prune the ones we don't want to keep
-        int N = mInstalledProviders.size();
-        for (int i = N - 1; i >= 0; i--) {
-            Provider p = mInstalledProviders.get(i);
-            cancelBroadcasts(p);
-        }
-    }
+    private void onUserStopped(int userId) {
+        synchronized (mLock) {
+            // Remove widgets that have both host and provider in the user.
+            final int widgetCount = mWidgets.size();
+            for (int i = widgetCount - 1; i >= 0; i--) {
+                Widget widget = mWidgets.get(i);
 
-    void onUserRemoved() {
-        getSettingsFile(mUserId).delete();
-    }
+                final boolean hostInUser = widget.host.getUserId() == userId;
+                final boolean hasProvider = widget.provider != null;
+                final boolean providerInUser = hasProvider && widget.provider.getUserId() == userId;
 
-    boolean addProvidersForPackageLocked(String pkgName) {
-        boolean providersAdded = false;
-        Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
-        intent.setPackage(pkgName);
-        List<ResolveInfo> broadcastReceivers;
-        try {
-            broadcastReceivers = mPm.queryIntentReceivers(intent,
-                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                    PackageManager.GET_META_DATA, mUserId);
-        } catch (RemoteException re) {
-            // Shouldn't happen, local call
-            return false;
-        }
-        final int N = broadcastReceivers == null ? 0 : broadcastReceivers.size();
-        for (int i = 0; i < N; i++) {
-            ResolveInfo ri = broadcastReceivers.get(i);
-            ActivityInfo ai = ri.activityInfo;
-            if ((ai.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
-                continue;
+                // If both host and provider are in the user, just drop the widgets
+                // as we do not want to make host callbacks and provider broadcasts
+                // as the host and the provider will be killed.
+                if (hostInUser && (!hasProvider || providerInUser)) {
+                    mWidgets.remove(i);
+                    widget.host.widgets.remove(widget);
+                    widget.host = null;
+                    if (hasProvider) {
+                        widget.provider.widgets.remove(widget);
+                        widget.provider = null;
+                    }
+                }
             }
-            if (pkgName.equals(ai.packageName)) {
-                providersAdded = addProviderLocked(ri);
+
+            // Remove hosts and notify providers in other profiles.
+            final int hostCount = mHosts.size();
+            for (int i = hostCount - 1; i >= 0; i--) {
+                Host host = mHosts.get(i);
+                if (host.getUserId() == userId) {
+                    deleteHostLocked(host);
+                }
+            }
+
+            // Remove the providers and notify hosts in other profiles.
+            final int providerCount = mProviders.size();
+            for (int i = providerCount - 1; i >= 0; i--) {
+                Provider provider = mProviders.get(i);
+                if (provider.getUserId() == userId) {
+                    deleteProviderLocked(provider);
+                }
+            }
+
+            // Remove grants for this user.
+            final int grantCount = mPackagesWithBindWidgetPermission.size();
+            for (int i = grantCount - 1; i >= 0; i--) {
+                Pair<Integer, String> packageId = mPackagesWithBindWidgetPermission.valueAt(i);
+                if (packageId.first == userId) {
+                    mPackagesWithBindWidgetPermission.removeAt(i);
+                }
+            }
+
+            // Take a note we no longer have state for this user.
+            final int userIndex = mLoadedUserIds.indexOfKey(userId);
+            if (userIndex >= 0) {
+                mLoadedUserIds.removeAt(userIndex);
+            }
+
+            // Remove the widget id counter.
+            final int nextIdIndex = mNextAppWidgetIds.indexOfKey(userId);
+            if (nextIdIndex >= 0) {
+                mNextAppWidgetIds.removeAt(nextIdIndex);
             }
         }
-
-        return providersAdded;
     }
 
     /**
@@ -2661,71 +2751,59 @@
      *
      * @return whether any providers were updated
      */
-    boolean updateProvidersForPackageLocked(String pkgName, Set<ComponentName> removedProviders) {
+    private boolean updateProvidersForPackageLocked(String packageName, int userId,
+            Set<ProviderId> removedProviders) {
         boolean providersUpdated = false;
-        HashSet<String> keep = new HashSet<String>();
+
+        HashSet<ProviderId> keep = new HashSet<>();
         Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
-        intent.setPackage(pkgName);
-        List<ResolveInfo> broadcastReceivers;
-        try {
-            broadcastReceivers = mPm.queryIntentReceivers(intent,
-                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                PackageManager.GET_META_DATA, mUserId);
-        } catch (RemoteException re) {
-            // Shouldn't happen, local call
-            return false;
-        }
+        intent.setPackage(packageName);
+        List<ResolveInfo> broadcastReceivers = queryIntentReceivers(intent, userId);
 
         // add the missing ones and collect which ones to keep
         int N = broadcastReceivers == null ? 0 : broadcastReceivers.size();
         for (int i = 0; i < N; i++) {
             ResolveInfo ri = broadcastReceivers.get(i);
             ActivityInfo ai = ri.activityInfo;
+
             if ((ai.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
                 continue;
             }
-            if (pkgName.equals(ai.packageName)) {
-                ComponentName component = new ComponentName(ai.packageName, ai.name);
-                Provider p = lookupProviderLocked(component);
-                if (p == null) {
+
+            if (packageName.equals(ai.packageName)) {
+                ProviderId providerId = new ProviderId(ai.applicationInfo.uid,
+                        new ComponentName(ai.packageName, ai.name));
+
+                Provider provider = lookupProviderLocked(providerId);
+                if (provider == null) {
                     if (addProviderLocked(ri)) {
-                        keep.add(ai.name);
+                        keep.add(providerId);
                         providersUpdated = true;
                     }
                 } else {
-                    Provider parsed = parseProviderInfoXml(component, ri);
+                    Provider parsed = parseProviderInfoXml(providerId, ri);
                     if (parsed != null) {
-                        keep.add(ai.name);
+                        keep.add(providerId);
                         // Use the new AppWidgetProviderInfo.
-                        p.info = parsed.info;
+                        provider.info = parsed.info;
                         // If it's enabled
-                        final int M = p.instances.size();
+                        final int M = provider.widgets.size();
                         if (M > 0) {
-                            int[] appWidgetIds = getAppWidgetIds(p);
+                            int[] appWidgetIds = getWidgetIds(provider.widgets);
                             // Reschedule for the new updatePeriodMillis (don't worry about handling
                             // it specially if updatePeriodMillis didn't change because we just sent
                             // an update, and the next one will be updatePeriodMillis from now).
-                            cancelBroadcasts(p);
-                            registerForBroadcastsLocked(p, appWidgetIds);
+                            cancelBroadcasts(provider);
+                            registerForBroadcastsLocked(provider, appWidgetIds);
                             // If it's currently showing, call back with the new
                             // AppWidgetProviderInfo.
                             for (int j = 0; j < M; j++) {
-                                AppWidgetId id = p.instances.get(j);
-                                id.views = null;
-                                if (id.host != null && id.host.callbacks != null) {
-                                    try {
-                                        id.host.callbacks.providerChanged(id.appWidgetId, p.info,
-                                                mUserId);
-                                    } catch (RemoteException ex) {
-                                        // It failed; remove the callback. No need to prune because
-                                        // we know that this host is still referenced by this
-                                        // instance.
-                                        id.host.callbacks = null;
-                                    }
-                                }
+                                Widget widget = provider.widgets.get(j);
+                                widget.views = null;
+                                scheduleNotifyProviderChangedLocked(widget);
                             }
                             // Now that we've told the host, push out an update.
-                            sendUpdateIntentLocked(p, appWidgetIds);
+                            sendUpdateIntentLocked(provider, appWidgetIds);
                             providersUpdated = true;
                         }
                     }
@@ -2734,15 +2812,16 @@
         }
 
         // prune the ones we don't want to keep
-        N = mInstalledProviders.size();
+        N = mProviders.size();
         for (int i = N - 1; i >= 0; i--) {
-            Provider p = mInstalledProviders.get(i);
-            if (pkgName.equals(p.info.provider.getPackageName())
-                    && !keep.contains(p.info.provider.getClassName())) {
+            Provider provider = mProviders.get(i);
+            if (packageName.equals(provider.info.provider.getPackageName())
+                    && provider.getUserId() == userId
+                    && !keep.contains(provider.id)) {
                 if (removedProviders != null) {
-                    removedProviders.add(p.info.provider);
+                    removedProviders.add(provider.id);
                 }
-                removeProviderLocked(i, p);
+                deleteProviderLocked(provider);
                 providersUpdated = true;
             }
         }
@@ -2750,46 +2829,1246 @@
         return providersUpdated;
     }
 
-    boolean removeProvidersForPackageLocked(String pkgName) {
-        boolean providersRemoved = false;
-        int N = mInstalledProviders.size();
+    private boolean removeHostsAndProvidersForPackageLocked(String pkgName, int userId) {
+        boolean removed = false;
+
+        int N = mProviders.size();
         for (int i = N - 1; i >= 0; i--) {
-            Provider p = mInstalledProviders.get(i);
-            if (pkgName.equals(p.info.provider.getPackageName())) {
-                removeProviderLocked(i, p);
-                providersRemoved = true;
+            Provider provider = mProviders.get(i);
+            if (pkgName.equals(provider.info.provider.getPackageName())
+                    && provider.getUserId() == userId) {
+                deleteProviderLocked(provider);
+                removed = true;
             }
         }
 
         // Delete the hosts for this package too
-        //
         // By now, we have removed any AppWidgets that were in any hosts here,
         // so we don't need to worry about sending DISABLE broadcasts to them.
         N = mHosts.size();
         for (int i = N - 1; i >= 0; i--) {
             Host host = mHosts.get(i);
-            if (pkgName.equals(host.packageName)) {
+            if (pkgName.equals(host.id.packageName)
+                    && host.getUserId() == userId) {
                 deleteHostLocked(host);
+                removed = true;
             }
         }
 
-        return providersRemoved;
+        return removed;
     }
 
-    void notifyHostsForProvidersChangedLocked() {
-        final int N = mHosts.size();
-        for (int i = N - 1; i >= 0; i--) {
-            Host host = mHosts.get(i);
+    private String getCanonicalPackageName(String packageName, String className, int userId) {
+        final long identity = Binder.clearCallingIdentity();
+        try {
             try {
-                if (host.callbacks != null) {
-                    host.callbacks.providersChanged(mUserId);
+                AppGlobals.getPackageManager().getReceiverInfo(new ComponentName(packageName,
+                        className), 0, userId);
+                return packageName;
+            } catch (RemoteException re) {
+                String[] packageNames = mContext.getPackageManager()
+                        .currentToCanonicalPackageNames(new String[]{packageName});
+                if (packageNames != null && packageNames.length > 0) {
+                    return packageNames[0];
                 }
-            } catch (RemoteException ex) {
-                // It failed; remove the callback. No need to prune because
-                // we know that this host is still referenced by this
-                // instance.
-                host.callbacks = null;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+        return null;
+    }
+
+    private void sendBroadcastAsUser(Intent intent, UserHandle userHandle) {
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            mContext.sendBroadcastAsUser(intent, userHandle);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    private void bindService(Intent intent, ServiceConnection connection,
+            UserHandle userHandle) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mContext.bindServiceAsUser(intent, connection, Context.BIND_AUTO_CREATE,
+                    userHandle);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    private void unbindService(ServiceConnection connection) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mContext.unbindService(connection);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    private final class CallbackHandler extends Handler {
+        public static final int MSG_NOTIFY_UPDATE_APP_WIDGET = 1;
+        public static final int MSG_NOTIFY_PROVIDER_CHANGED = 2;
+        public static final int MSG_NOTIFY_PROVIDERS_CHANGED = 3;
+        public static final int MSG_NOTIFY_VIEW_DATA_CHANGED = 4;
+
+        public CallbackHandler(Looper looper) {
+            super(looper, null, false);
+        }
+
+        @Override
+        public void handleMessage(Message message) {
+            switch (message.what) {
+                case MSG_NOTIFY_UPDATE_APP_WIDGET: {
+                    SomeArgs args = (SomeArgs) message.obj;
+                    Host host = (Host) args.arg1;
+                    IAppWidgetHost callbacks = (IAppWidgetHost) args.arg2;
+                    RemoteViews views = (RemoteViews) args.arg3;
+                    final int appWidgetId = args.argi1;
+                    args.recycle();
+
+                    handleNotifyUpdateAppWidget(host, callbacks, appWidgetId, views);
+                } break;
+
+                case MSG_NOTIFY_PROVIDER_CHANGED: {
+                    SomeArgs args = (SomeArgs) message.obj;
+                    Host host = (Host) args.arg1;
+                    IAppWidgetHost callbacks = (IAppWidgetHost) args.arg2;
+                    AppWidgetProviderInfo info = (AppWidgetProviderInfo)args.arg3;
+                    final int appWidgetId = args.argi1;
+                    args.recycle();
+
+                    handleNotifyProviderChanged(host, callbacks, appWidgetId, info);
+                } break;
+
+                case MSG_NOTIFY_PROVIDERS_CHANGED: {
+                    SomeArgs args = (SomeArgs) message.obj;
+                    Host host = (Host) args.arg1;
+                    IAppWidgetHost callbacks = (IAppWidgetHost) args.arg2;
+                    args.recycle();
+
+                    handleNotifyProvidersChanged(host, callbacks);
+                } break;
+
+                case MSG_NOTIFY_VIEW_DATA_CHANGED: {
+                    SomeArgs args = (SomeArgs) message.obj;
+                    Host host = (Host) args.arg1;
+                    IAppWidgetHost callbacks = (IAppWidgetHost) args.arg2;
+                    final int appWidgetId = args.argi1;
+                    final int viewId = args.argi2;
+                    args.recycle();
+
+                    handleNotifyAppWidgetViewDataChanged(host, callbacks, appWidgetId, viewId);
+                } break;
             }
         }
     }
-}
+
+    private final class SecurityPolicy {
+
+        public int[] resolveCallerEnabledGroupProfiles(int[] profileIds) {
+            final int parentId = UserHandle.getCallingUserId();
+
+            int enabledProfileCount = 0;
+            final int profileCount = profileIds.length;
+            for (int i = 0; i < profileCount; i++) {
+                final int profileId = profileIds[i];
+                if (!isParentOrProfile(parentId, profileId)) {
+                    throw new SecurityException("Not the current user or"
+                            + " a child profile: " + profileId);
+                }
+                if (!isProfileEnabled(profileId)) {
+                    profileIds[i] = DISABLED_PROFILE;
+                } else {
+                    enabledProfileCount++;
+                }
+            }
+
+            int resolvedProfileIndex = 0;
+            final int[] resolvedProfiles = new int[enabledProfileCount];
+            for (int i = 0; i < profileCount; i++) {
+                final int profileId = profileIds[i];
+                if (profileId != DISABLED_PROFILE) {
+                    resolvedProfiles[resolvedProfileIndex] = profileId;
+                    resolvedProfileIndex++;
+                }
+            }
+
+            return resolvedProfiles;
+        }
+
+        public int[] getEnabledGroupProfileIds(int userId) {
+            final int parentId = getGroupParent(userId);
+
+            final List<UserInfo> profiles;
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                profiles = mUserManager.getProfiles(parentId);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+
+            int enabledProfileCount = 0;
+            final int profileCount = profiles.size();
+            for (int i = 0; i < profileCount; i++) {
+                if (profiles.get(i).isEnabled()) {
+                    enabledProfileCount++;
+                }
+            }
+
+            int enabledProfileIndex = 0;
+            final int[] profileIds = new int[enabledProfileCount];
+            for (int i = 0; i < profileCount; i++) {
+                UserInfo profile = profiles.get(i);
+                if (profile.isEnabled()) {
+                    profileIds[enabledProfileIndex] = profile.getUserHandle().getIdentifier();
+                    enabledProfileIndex++;
+                }
+            }
+
+            return profileIds;
+        }
+
+        public void enforceServiceExistsAndRequiresBindRemoteViewsPermission(
+                ComponentName componentName, int userId) {
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                ServiceInfo serviceInfo = mPackageManager.getServiceInfo(componentName,
+                        PackageManager.GET_PERMISSIONS, userId);
+                if (serviceInfo == null) {
+                    throw new SecurityException("Service " + componentName
+                            + " not installed for user " + userId);
+                }
+                if (!android.Manifest.permission.BIND_REMOTEVIEWS.equals(serviceInfo.permission)) {
+                    throw new SecurityException("Service " + componentName
+                            + " in user " + userId + "does not require "
+                            + android.Manifest.permission.BIND_REMOTEVIEWS);
+                }
+            } catch (RemoteException re) {
+                // Local call - shouldn't happen.
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+
+        public void enforceModifyAppWidgetBindPermissions(String packageName) {
+            mContext.enforceCallingPermission(
+                    android.Manifest.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS,
+                    "hasBindAppWidgetPermission packageName=" + packageName);
+        }
+
+        public void enforceCallFromPackage(String packageName) {
+            if (!isCallFromPackage(packageName)) {
+                throw new SecurityException("Package " + packageName
+                        + " not running under user " + UserHandle.getCallingUserId());
+            }
+        }
+
+        public boolean isCallFromPackage(String packageName) {
+            // System and root call all from anywhere they want.
+            final int callingUid = Binder.getCallingUid();
+            if (callingUid == Process.SYSTEM_UID || callingUid == 0 /* root */) {
+                return true;
+            }
+            // Check if the package is present for the given profile.
+            final int packageUid = getUidForPackage(packageName,
+                    UserHandle.getUserId(callingUid));
+            if (packageUid < 0) {
+                return false;
+            }
+            // Check if the call for a package is coming from that package.
+            return UserHandle.isSameApp(callingUid, packageUid);
+        }
+
+        public boolean hasCallerBindPermissionOrBindWhiteListedLocked(String packageName) {
+            try {
+                mContext.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.BIND_APPWIDGET, null);
+            } catch (SecurityException se) {
+                if (!isCallerBindAppWidgetWhiteListedLocked(packageName)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        private boolean isCallerBindAppWidgetWhiteListedLocked(String packageName) {
+            final int userId = UserHandle.getCallingUserId();
+            final int packageUid = getUidForPackage(packageName, userId);
+            if (packageUid < 0) {
+                throw new IllegalArgumentException("No package " + packageName
+                        + " for user " + userId);
+            }
+            synchronized (mLock) {
+                ensureGroupStateLoadedLocked(userId);
+
+                Pair<Integer, String> packageId = Pair.create(userId, packageName);
+                if (mPackagesWithBindWidgetPermission.contains(packageId)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        public boolean canAccessAppWidget(Widget widget, int uid, String packageName) {
+            if (isHostInPackageForUid(widget.host, uid, packageName)) {
+                // Apps hosting the AppWidget have access to it.
+                return true;
+            }
+            if (isProviderInPackageForUid(widget.provider, uid, packageName)) {
+                // Apps providing the AppWidget have access to it.
+                return true;
+            }
+            if (isHostAccessingProvider(widget.host, widget.provider, uid, packageName)) {
+                // Apps hosting the AppWidget get to bind to a remote view service in the provider.
+                return true;
+            }
+            final int userId = UserHandle.getUserId(uid);
+            if ((widget.host.getUserId() == userId || (widget.provider != null
+                    && widget.provider.getUserId() == userId))
+                && mContext.checkCallingPermission(android.Manifest.permission.BIND_APPWIDGET)
+                    == PackageManager.PERMISSION_GRANTED) {
+                // Apps that run in the same user as either the host or the provider and
+                // have the bind widget permission have access to the widget.
+                return true;
+            }
+            return false;
+        }
+
+        private boolean isParentOrProfile(int parentId, int profileId) {
+            if (parentId == profileId) {
+                return true;
+            }
+            return getProfileParent(profileId) == parentId;
+        }
+
+        public boolean isProviderInCallerOrInProfileAndWhitelListed(String packageName,
+                int profileId) {
+            final int callerId = UserHandle.getCallingUserId();
+            if (profileId == callerId) {
+                return true;
+            }
+            final int parentId = getProfileParent(profileId);
+            if (parentId != callerId) {
+                return false;
+            }
+            return isProviderWhitelListed(packageName, profileId);
+        }
+
+        public boolean isProviderWhitelListed(String packageName, int profileId) {
+            DevicePolicyManagerInternal devicePolicyManager = LocalServices.getService(
+                    DevicePolicyManagerInternal.class);
+
+            // If the policy manager is not available on the device we deny it all.
+            if (devicePolicyManager == null) {
+                return false;
+            }
+
+            List<String> crossProfilePackages = devicePolicyManager
+                    .getCrossProfileWidgetProviders(profileId);
+
+            return crossProfilePackages.contains(packageName);
+        }
+
+        public int getProfileParent(int profileId) {
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                UserInfo parent = mUserManager.getProfileParent(profileId);
+                if (parent != null) {
+                    return parent.getUserHandle().getIdentifier();
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+            return UNKNOWN_USER_ID;
+        }
+
+        public int getGroupParent(int profileId) {
+            final int parentId = mSecurityPolicy.getProfileParent(profileId);
+            return (parentId != UNKNOWN_USER_ID) ? parentId : profileId;
+        }
+
+        public boolean isHostInPackageForUid(Host host, int uid, String packageName) {
+            return host.id.uid == uid && host.id.packageName.equals(packageName);
+        }
+
+        public boolean isProviderInPackageForUid(Provider provider, int uid,
+                String packageName) {
+            // Packages providing the AppWidget have access to it.
+            return provider != null && provider.id.uid == uid
+                    && provider.id.componentName.getPackageName().equals(packageName);
+        }
+
+        public boolean isHostAccessingProvider(Host host, Provider provider, int uid,
+                String packageName) {
+            // The host creates a package context to bind to remote views service in the provider.
+            return host.id.uid == uid && provider != null
+                    && provider.id.componentName.getPackageName().equals(packageName);
+        }
+
+        private boolean isProfileEnabled(int profileId) {
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                UserInfo userInfo = mUserManager.getUserInfo(profileId);
+                if (userInfo == null || !userInfo.isEnabled()) {
+                    return false;
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+            return true;
+        }
+    }
+
+    private static final class Provider {
+        ProviderId id;
+        AppWidgetProviderInfo info;
+        ArrayList<Widget> widgets = new ArrayList<>();
+        PendingIntent broadcast;
+        boolean zombie; // if we're in safe mode, don't prune this just because nobody references it
+
+        int tag = TAG_UNDEFINED; // for use while saving state (the index)
+
+        public int getUserId() {
+            return UserHandle.getUserId(id.uid);
+        }
+
+        public boolean isInPackageForUser(String packageName, int userId) {
+            return getUserId() == userId
+                    && id.componentName.getPackageName().equals(packageName);
+        }
+
+        // is there an instance of this provider hosted by the given app?
+        public boolean hostedByPackageForUser(String packageName, int userId) {
+            final int N = widgets.size();
+            for (int i = 0; i < N; i++) {
+                Widget widget = widgets.get(i);
+                if (packageName.equals(widget.host.id.packageName)
+                        && widget.host.getUserId() == userId) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "Provider{" + id + (zombie ? " Z" : "") + '}';
+        }
+    }
+
+    private static final class ProviderId {
+        final int uid;
+        final ComponentName componentName;
+
+        private ProviderId(int uid, ComponentName componentName) {
+            this.uid = uid;
+            this.componentName = componentName;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            ProviderId other = (ProviderId) obj;
+            if (uid != other.uid)  {
+                return false;
+            }
+            if (componentName == null) {
+                if (other.componentName != null) {
+                    return false;
+                }
+            } else if (!componentName.equals(other.componentName)) {
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = uid;
+            result = 31 * result + ((componentName != null)
+                    ? componentName.hashCode() : 0);
+            return result;
+        }
+
+        @Override
+        public String toString() {
+            return "ProviderId{user:" + UserHandle.getUserId(uid) + ", app:"
+                    + UserHandle.getAppId(uid) + ", cmp:" + componentName + '}';
+        }
+    }
+
+    private static final class Host {
+        HostId id;
+        ArrayList<Widget> widgets = new ArrayList<>();
+        IAppWidgetHost callbacks;
+        boolean zombie; // if we're in safe mode, don't prune this just because nobody references it
+
+        int tag = TAG_UNDEFINED; // for use while saving state (the index)
+
+        public int getUserId() {
+            return UserHandle.getUserId(id.uid);
+        }
+
+        public boolean isInPackageForUser(String packageName, int userId) {
+            return getUserId() == userId && id.packageName.equals(packageName);
+        }
+
+        private boolean hostsPackageForUser(String pkg, int userId) {
+            final int N = widgets.size();
+            for (int i = 0; i < N; i++) {
+                Provider provider = widgets.get(i).provider;
+                if (provider != null && provider.getUserId() == userId && provider.info != null
+                        && pkg.equals(provider.info.provider.getPackageName())) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "Host{" + id + (zombie ? " Z" : "") + '}';
+        }
+    }
+
+    private static final class HostId {
+        final int uid;
+        final int hostId;
+        final String packageName;
+
+        public HostId(int uid, int hostId, String packageName) {
+            this.uid = uid;
+            this.hostId = hostId;
+            this.packageName = packageName;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            HostId other = (HostId) obj;
+            if (uid != other.uid)  {
+                return false;
+            }
+            if (hostId != other.hostId) {
+                return false;
+            }
+            if (packageName == null) {
+                if (other.packageName != null) {
+                    return false;
+                }
+            } else if (!packageName.equals(other.packageName)) {
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = uid;
+            result = 31 * result + hostId;
+            result = 31 * result + ((packageName != null)
+                    ? packageName.hashCode() : 0);
+            return result;
+        }
+
+        @Override
+        public String toString() {
+            return "HostId{user:" + UserHandle.getUserId(uid) + ", app:"
+                    + UserHandle.getAppId(uid) + ", hostId:" + hostId
+                    + ", pkg:" + packageName + '}';
+        }
+    }
+
+    private static final class Widget {
+        int appWidgetId;
+        int restoredId;  // tracking & remapping any restored state
+        Provider provider;
+        RemoteViews views;
+        Bundle options;
+        Host host;
+
+        @Override
+        public String toString() {
+            return "AppWidgetId{" + appWidgetId + ':' + host + ':' + provider + '}';
+        }
+    }
+
+    /**
+     * Acts as a proxy between the ServiceConnection and the RemoteViewsAdapterConnection. This
+     * needs to be a static inner class since a reference to the ServiceConnection is held globally
+     * and may lead us to leak AppWidgetService instances (if there were more than one).
+     */
+    private static final class ServiceConnectionProxy implements ServiceConnection {
+        private final IRemoteViewsAdapterConnection mConnectionCb;
+
+        ServiceConnectionProxy(IBinder connectionCb) {
+            mConnectionCb = IRemoteViewsAdapterConnection.Stub
+                    .asInterface(connectionCb);
+        }
+
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            try {
+                mConnectionCb.onServiceConnected(service);
+            } catch (RemoteException re) {
+                Slog.e(TAG, "Error passing service interface", re);
+            }
+        }
+
+        public void onServiceDisconnected(ComponentName name) {
+            disconnect();
+        }
+
+        public void disconnect() {
+            try {
+                mConnectionCb.onServiceDisconnected();
+            } catch (RemoteException re) {
+                Slog.e(TAG, "Error clearing service interface", re);
+            }
+        }
+    }
+
+    private class LoadedWidgetState {
+        final Widget widget;
+        final int hostTag;
+        final int providerTag;
+
+        public LoadedWidgetState(Widget widget, int hostTag, int providerTag) {
+            this.widget = widget;
+            this.hostTag = hostTag;
+            this.providerTag = providerTag;
+        }
+    }
+
+    private final class SaveStateRunnable implements Runnable {
+        final int mUserId;
+
+        public SaveStateRunnable(int userId) {
+            mUserId = userId;
+        }
+
+        @Override
+        public void run() {
+            synchronized (mLock) {
+                ensureGroupStateLoadedLocked(mUserId);
+                saveStateLocked(mUserId);
+            }
+        }
+    }
+
+    /**
+     * This class encapsulates the backup and restore logic for a user group state.
+     */
+    private final class BackupRestoreController {
+        private static final String TAG = "BackupRestoreController";
+
+        private static final boolean DEBUG = true;
+
+        // Version of backed-up widget state.
+        private static final int WIDGET_STATE_VERSION = 2;
+
+        // We need to make sure to wipe the pre-restore widget state only once for
+        // a given package.  Keep track of what we've done so far here; the list is
+        // cleared at the start of every system restore pass, but preserved through
+        // any install-time restore operations.
+        private final HashSet<String> mPrunedApps = new HashSet<>();
+
+        private final HashMap<Provider, ArrayList<RestoreUpdateRecord>> mUpdatesByProvider =
+                new HashMap<>();
+        private final HashMap<Host, ArrayList<RestoreUpdateRecord>> mUpdatesByHost =
+                new HashMap<>();
+
+        public List<String> getWidgetParticipants(int userId) {
+            if (DEBUG) {
+                Slog.i(TAG, "Getting widget participants for user: " + userId);
+            }
+
+            HashSet<String> packages = new HashSet<>();
+            synchronized (mLock) {
+                final int N = mWidgets.size();
+                for (int i = 0; i < N; i++) {
+                    Widget widget = mWidgets.get(i);
+
+                    // Skip cross-user widgets.
+                    if (!isProviderAndHostInUser(widget, userId)) {
+                        continue;
+                    }
+
+                    packages.add(widget.host.id.packageName);
+                    Provider provider = widget.provider;
+                    if (provider != null) {
+                        packages.add(provider.id.componentName.getPackageName());
+                    }
+                }
+            }
+            return new ArrayList<>(packages);
+        }
+
+        public byte[] getWidgetState(String backedupPackage, int userId) {
+            if (DEBUG) {
+                Slog.i(TAG, "Getting widget state for user: " + userId);
+            }
+
+            ByteArrayOutputStream stream = new ByteArrayOutputStream();
+            synchronized (mLock) {
+                // Preflight: if this app neither hosts nor provides any live widgets
+                // we have no work to do.
+                if (!packageNeedsWidgetBackupLocked(backedupPackage, userId)) {
+                    return null;
+                }
+
+                try {
+                    XmlSerializer out = new FastXmlSerializer();
+                    out.setOutput(stream, "utf-8");
+                    out.startDocument(null, true);
+                    out.startTag(null, "ws");      // widget state
+                    out.attribute(null, "version", String.valueOf(WIDGET_STATE_VERSION));
+                    out.attribute(null, "pkg", backedupPackage);
+
+                    // Remember all the providers that are currently hosted or published
+                    // by this package: that is, all of the entities related to this app
+                    // which will need to be told about id remapping.
+                    int index = 0;
+                    int N = mProviders.size();
+                    for (int i = 0; i < N; i++) {
+                        Provider provider = mProviders.get(i);
+
+                        if (!provider.widgets.isEmpty()
+                                && (provider.isInPackageForUser(backedupPackage, userId)
+                                || provider.hostedByPackageForUser(backedupPackage, userId))) {
+                            provider.tag = index;
+                            serializeProvider(out, provider);
+                            index++;
+                        }
+                    }
+
+                    N = mHosts.size();
+                    index = 0;
+                    for (int i = 0; i < N; i++) {
+                        Host host = mHosts.get(i);
+
+                        if (!host.widgets.isEmpty()
+                                && (host.isInPackageForUser(backedupPackage, userId)
+                                || host.hostsPackageForUser(backedupPackage, userId))) {
+                            host.tag = index;
+                            serializeHost(out, host);
+                            index++;
+                        }
+                    }
+
+                    // All widget instances involving this package,
+                    // either as host or as provider
+                    N = mWidgets.size();
+                    for (int i = 0; i < N; i++) {
+                        Widget widget = mWidgets.get(i);
+
+                        Provider provider = widget.provider;
+                        if (widget.host.isInPackageForUser(backedupPackage, userId)
+                                || (provider != null
+                                &&  provider.isInPackageForUser(backedupPackage, userId))) {
+                            serializeAppWidget(out, widget);
+                        }
+                    }
+
+                    out.endTag(null, "ws");
+                    out.endDocument();
+                } catch (IOException e) {
+                    Slog.w(TAG, "Unable to save widget state for " + backedupPackage);
+                    return null;
+                }
+            }
+
+            return stream.toByteArray();
+        }
+
+        public void restoreStarting(int userId) {
+            if (DEBUG) {
+                Slog.i(TAG, "Restore starting for user: " + userId);
+            }
+
+            synchronized (mLock) {
+                // We're starting a new "system" restore operation, so any widget restore
+                // state that we see from here on is intended to replace the current
+                // widget configuration of any/all of the affected apps.
+                mPrunedApps.clear();
+                mUpdatesByProvider.clear();
+                mUpdatesByHost.clear();
+            }
+        }
+
+        public void restoreWidgetState(String packageName, byte[] restoredState, int userId) {
+            if (DEBUG) {
+                Slog.i(TAG, "Restoring widget state for user:" + userId
+                        + " package: " + packageName);
+            }
+
+            ByteArrayInputStream stream = new ByteArrayInputStream(restoredState);
+            try {
+                // Providers mentioned in the widget dataset by ordinal
+                ArrayList<Provider> restoredProviders = new ArrayList<>();
+
+                // Hosts mentioned in the widget dataset by ordinal
+                ArrayList<Host> restoredHosts = new ArrayList<>();
+
+                XmlPullParser parser = Xml.newPullParser();
+                parser.setInput(stream, null);
+
+                synchronized (mLock) {
+                    int type;
+                    do {
+                        type = parser.next();
+                        if (type == XmlPullParser.START_TAG) {
+                            final String tag = parser.getName();
+                            if ("ws".equals(tag)) {
+                                String version = parser.getAttributeValue(null, "version");
+
+                                final int versionNumber = Integer.parseInt(version);
+                                if (versionNumber > WIDGET_STATE_VERSION) {
+                                    Slog.w(TAG, "Unable to process state version " + version);
+                                    return;
+                                }
+
+                                // TODO: fix up w.r.t. canonical vs current package names
+                                String pkg = parser.getAttributeValue(null, "pkg");
+                                if (!packageName.equals(pkg)) {
+                                    Slog.w(TAG, "Package mismatch in ws");
+                                    return;
+                                }
+                            } else if ("p".equals(tag)) {
+                                String pkg = parser.getAttributeValue(null, "pkg");
+                                String cl = parser.getAttributeValue(null, "cl");
+
+                                // hostedProviders index will match 'p' attribute in widget's
+                                // entry in the xml file being restored
+                                // If there's no live entry for this provider, add an inactive one
+                                // so that widget IDs referring to them can be properly allocated
+
+                                // Backup and resotre only for the parent profile.
+                                ComponentName componentName = new ComponentName(pkg, cl);
+
+                                Provider p = findProviderLocked(componentName, userId);
+                                if (p == null) {
+                                    p = new Provider();
+                                    p.id = new ProviderId(UNKNOWN_UID, componentName);
+                                    p.info = new AppWidgetProviderInfo();
+                                    p.info.provider = componentName;
+                                    p.zombie = true;
+                                    mProviders.add(p);
+                                }
+                                if (DEBUG) {
+                                    Slog.i(TAG, "   provider " + p.id);
+                                }
+                                restoredProviders.add(p);
+                            } else if ("h".equals(tag)) {
+                                // The host app may not yet exist on the device.  If it's here we
+                                // just use the existing Host entry, otherwise we create a
+                                // placeholder whose uid will be fixed up at PACKAGE_ADDED time.
+                                String pkg = parser.getAttributeValue(null, "pkg");
+
+                                final int uid = getUidForPackage(pkg, userId);
+                                final int hostId = Integer.parseInt(
+                                        parser.getAttributeValue(null, "id"), 16);
+
+                                HostId id = new HostId(uid, hostId, pkg);
+                                Host h = lookupOrAddHostLocked(id);
+                                restoredHosts.add(h);
+
+                                if (DEBUG) {
+                                    Slog.i(TAG, "   host[" + restoredHosts.size()
+                                            + "]: {" + h.id + "}");
+                                }
+                            } else if ("g".equals(tag)) {
+                                int restoredId = Integer.parseInt(
+                                        parser.getAttributeValue(null, "id"), 16);
+                                int hostIndex = Integer.parseInt(
+                                        parser.getAttributeValue(null, "h"), 16);
+                                Host host = restoredHosts.get(hostIndex);
+                                Provider p = null;
+                                String prov = parser.getAttributeValue(null, "p");
+                                if (prov != null) {
+                                    // could have been null if the app had allocated an id
+                                    // but not yet established a binding under that id
+                                    int which = Integer.parseInt(prov, 16);
+                                    p = restoredProviders.get(which);
+                                }
+
+                                // We'll be restoring widget state for both the host and
+                                // provider sides of this widget ID, so make sure we are
+                                // beginning from a clean slate on both fronts.
+                                pruneWidgetStateLocked(host.id.packageName, userId);
+                                if (p != null) {
+                                    pruneWidgetStateLocked(p.id.componentName.getPackageName(),
+                                            userId);
+                                }
+
+                                // Have we heard about this ancestral widget instance before?
+                                Widget id = findRestoredWidgetLocked(restoredId, host, p);
+                                if (id == null) {
+                                    id = new Widget();
+                                    id.appWidgetId = incrementAndGetAppWidgetIdLocked(userId);
+                                    id.restoredId = restoredId;
+                                    id.options = parseWidgetIdOptions(parser);
+                                    id.host = host;
+                                    id.host.widgets.add(id);
+                                    id.provider = p;
+                                    if (id.provider != null) {
+                                        id.provider.widgets.add(id);
+                                    }
+                                    if (DEBUG) {
+                                        Slog.i(TAG, "New restored id " + restoredId
+                                                + " now " + id);
+                                    }
+                                    mWidgets.add(id);
+                                }
+                                if (id.provider.info != null) {
+                                    stashProviderRestoreUpdateLocked(id.provider,
+                                            restoredId, id.appWidgetId);
+                                } else {
+                                    Slog.w(TAG, "Missing provider for restored widget " + id);
+                                }
+                                stashHostRestoreUpdateLocked(id.host, restoredId, id.appWidgetId);
+
+                                if (DEBUG) {
+                                    Slog.i(TAG, "   instance: " + restoredId
+                                            + " -> " + id.appWidgetId
+                                            + " :: p=" + id.provider);
+                                }
+                            }
+                        }
+                    } while (type != XmlPullParser.END_DOCUMENT);
+
+                    // We've updated our own bookkeeping.  We'll need to notify the hosts and
+                    // providers about the changes, but we can't do that yet because the restore
+                    // target is not necessarily fully live at this moment.  Set aside the
+                    // information for now; the backup manager will call us once more at the
+                    // end of the process when all of the targets are in a known state, and we
+                    // will update at that point.
+                }
+            } catch (XmlPullParserException | IOException e) {
+                Slog.w(TAG, "Unable to restore widget state for " + packageName);
+            } finally {
+                saveGroupStateAsync(userId);
+            }
+        }
+
+        // Called once following the conclusion of a restore operation.  This is when we
+        // send out updates to apps involved in widget-state restore telling them about
+        // the new widget ID space.
+        public void restoreFinished(int userId) {
+            if (DEBUG) {
+                Slog.i(TAG, "restoreFinished for " + userId);
+            }
+
+            final UserHandle userHandle = new UserHandle(userId);
+            synchronized (mLock) {
+                // Build the providers' broadcasts and send them off
+                Set<Map.Entry<Provider, ArrayList<RestoreUpdateRecord>>> providerEntries
+                        = mUpdatesByProvider.entrySet();
+                for (Map.Entry<Provider, ArrayList<RestoreUpdateRecord>> e : providerEntries) {
+                    // For each provider there's a list of affected IDs
+                    Provider provider = e.getKey();
+                    ArrayList<RestoreUpdateRecord> updates = e.getValue();
+                    final int pending = countPendingUpdates(updates);
+                    if (DEBUG) {
+                        Slog.i(TAG, "Provider " + provider + " pending: " + pending);
+                    }
+                    if (pending > 0) {
+                        int[] oldIds = new int[pending];
+                        int[] newIds = new int[pending];
+                        final int N = updates.size();
+                        int nextPending = 0;
+                        for (int i = 0; i < N; i++) {
+                            RestoreUpdateRecord r = updates.get(i);
+                            if (!r.notified) {
+                                r.notified = true;
+                                oldIds[nextPending] = r.oldId;
+                                newIds[nextPending] = r.newId;
+                                nextPending++;
+                                if (DEBUG) {
+                                    Slog.i(TAG, "   " + r.oldId + " => " + r.newId);
+                                }
+                            }
+                        }
+                        sendWidgetRestoreBroadcastLocked(
+                                AppWidgetManager.ACTION_APPWIDGET_RESTORED,
+                                provider, null, oldIds, newIds, userHandle);
+                    }
+                }
+
+                // same thing per host
+                Set<Map.Entry<Host, ArrayList<RestoreUpdateRecord>>> hostEntries
+                        = mUpdatesByHost.entrySet();
+                for (Map.Entry<Host, ArrayList<RestoreUpdateRecord>> e : hostEntries) {
+                    Host host = e.getKey();
+                    if (host.id.uid != UNKNOWN_UID) {
+                        ArrayList<RestoreUpdateRecord> updates = e.getValue();
+                        final int pending = countPendingUpdates(updates);
+                        if (DEBUG) {
+                            Slog.i(TAG, "Host " + host + " pending: " + pending);
+                        }
+                        if (pending > 0) {
+                            int[] oldIds = new int[pending];
+                            int[] newIds = new int[pending];
+                            final int N = updates.size();
+                            int nextPending = 0;
+                            for (int i = 0; i < N; i++) {
+                                RestoreUpdateRecord r = updates.get(i);
+                                if (!r.notified) {
+                                    r.notified = true;
+                                    oldIds[nextPending] = r.oldId;
+                                    newIds[nextPending] = r.newId;
+                                    nextPending++;
+                                    if (DEBUG) {
+                                        Slog.i(TAG, "   " + r.oldId + " => " + r.newId);
+                                    }
+                                }
+                            }
+                            sendWidgetRestoreBroadcastLocked(
+                                    AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED,
+                                    null, host, oldIds, newIds, userHandle);
+                        }
+                    }
+                }
+            }
+        }
+
+        private Provider findProviderLocked(ComponentName componentName, int userId) {
+            final int providerCount = mProviders.size();
+            for (int i = 0; i < providerCount; i++) {
+                Provider provider = mProviders.get(i);
+                if (provider.getUserId() == userId
+                        && provider.id.componentName.equals(componentName)) {
+                    return provider;
+                }
+            }
+            return null;
+        }
+
+        private Widget findRestoredWidgetLocked(int restoredId, Host host, Provider p) {
+            if (DEBUG) {
+                Slog.i(TAG, "Find restored widget: id=" + restoredId
+                        + " host=" + host + " provider=" + p);
+            }
+
+            if (p == null || host == null) {
+                return null;
+            }
+
+            final int N = mWidgets.size();
+            for (int i = 0; i < N; i++) {
+                Widget widget = mWidgets.get(i);
+                if (widget.restoredId == restoredId
+                        && widget.host.id.equals(host.id)
+                        && widget.provider.id.equals(p.id)) {
+                    if (DEBUG) {
+                        Slog.i(TAG, "   Found at " + i + " : " + widget);
+                    }
+                    return widget;
+                }
+            }
+            return null;
+        }
+
+        private boolean packageNeedsWidgetBackupLocked(String packageName, int userId) {
+            int N = mWidgets.size();
+            for (int i = 0; i < N; i++) {
+                Widget widget = mWidgets.get(i);
+
+                // Skip cross-user widgets.
+                if (!isProviderAndHostInUser(widget, userId)) {
+                    continue;
+                }
+
+                if (widget.host.isInPackageForUser(packageName, userId)) {
+                    // this package is hosting widgets, so it knows widget IDs.
+                    return true;
+                }
+
+                Provider provider = widget.provider;
+                if (provider != null && provider.isInPackageForUser(packageName, userId)) {
+                    // someone is hosting this app's widgets, so it knows widget IDs.
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        private void stashProviderRestoreUpdateLocked(Provider provider, int oldId, int newId) {
+            ArrayList<RestoreUpdateRecord> r = mUpdatesByProvider.get(provider);
+            if (r == null) {
+                r = new ArrayList<>();
+                mUpdatesByProvider.put(provider, r);
+            } else {
+                // don't duplicate
+                if (alreadyStashed(r, oldId, newId)) {
+                    if (DEBUG) {
+                        Slog.i(TAG, "ID remap " + oldId + " -> " + newId
+                                + " already stashed for " + provider);
+                    }
+                    return;
+                }
+            }
+            r.add(new RestoreUpdateRecord(oldId, newId));
+        }
+
+        private boolean alreadyStashed(ArrayList<RestoreUpdateRecord> stash,
+                final int oldId, final int newId) {
+            final int N = stash.size();
+            for (int i = 0; i < N; i++) {
+                RestoreUpdateRecord r = stash.get(i);
+                if (r.oldId == oldId && r.newId == newId) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        private void stashHostRestoreUpdateLocked(Host host, int oldId, int newId) {
+            ArrayList<RestoreUpdateRecord> r = mUpdatesByHost.get(host);
+            if (r == null) {
+                r = new ArrayList<>();
+                mUpdatesByHost.put(host, r);
+            } else {
+                if (alreadyStashed(r, oldId, newId)) {
+                    if (DEBUG) {
+                        Slog.i(TAG, "ID remap " + oldId + " -> " + newId
+                                + " already stashed for " + host);
+                    }
+                    return;
+                }
+            }
+            r.add(new RestoreUpdateRecord(oldId, newId));
+        }
+
+        private void sendWidgetRestoreBroadcastLocked(String action, Provider provider,
+                Host host, int[] oldIds, int[] newIds, UserHandle userHandle) {
+            Intent intent = new Intent(action);
+            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS, oldIds);
+            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, newIds);
+            if (provider != null) {
+                intent.setComponent(provider.info.provider);
+                sendBroadcastAsUser(intent, userHandle);
+            }
+            if (host != null) {
+                intent.setComponent(null);
+                intent.setPackage(host.id.packageName);
+                intent.putExtra(AppWidgetManager.EXTRA_HOST_ID, host.id.hostId);
+                sendBroadcastAsUser(intent, userHandle);
+            }
+        }
+
+        // We're restoring widget state for 'pkg', so we start by wiping (a) all widget
+        // instances that are hosted by that app, and (b) all instances in other hosts
+        // for which 'pkg' is the provider.  We assume that we'll be restoring all of
+        // these hosts & providers, so will be reconstructing a correct live state.
+        private void pruneWidgetStateLocked(String pkg, int userId) {
+            if (!mPrunedApps.contains(pkg)) {
+                if (DEBUG) {
+                    Slog.i(TAG, "pruning widget state for restoring package " + pkg);
+                }
+                for (int i = mWidgets.size() - 1; i >= 0; i--) {
+                    Widget widget = mWidgets.get(i);
+
+                    Host host = widget.host;
+                    Provider provider = widget.provider;
+
+                    if (host.hostsPackageForUser(pkg, userId)
+                            || (provider != null && provider.isInPackageForUser(pkg, userId))) {
+                        // 'pkg' is either the host or the provider for this instances,
+                        // so we tear it down in anticipation of it (possibly) being
+                        // reconstructed due to the restore
+                        host.widgets.remove(widget);
+                        provider.widgets.remove(widget);
+                        unbindAppWidgetRemoteViewsServicesLocked(widget);
+                        mWidgets.remove(i);
+                    }
+                }
+                mPrunedApps.add(pkg);
+            } else {
+                if (DEBUG) {
+                    Slog.i(TAG, "already pruned " + pkg + ", continuing normally");
+                }
+            }
+        }
+
+        private boolean isProviderAndHostInUser(Widget widget, int userId) {
+            // Backup only widgets hosted or provided by the owner profile.
+            return widget.host.getUserId() == userId && (widget.provider == null
+                    || widget.provider.getUserId() == userId);
+        }
+
+        private Bundle parseWidgetIdOptions(XmlPullParser parser) {
+            Bundle options = new Bundle();
+            String minWidthString = parser.getAttributeValue(null, "min_width");
+            if (minWidthString != null) {
+                options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH,
+                        Integer.parseInt(minWidthString, 16));
+            }
+            String minHeightString = parser.getAttributeValue(null, "min_height");
+            if (minHeightString != null) {
+                options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT,
+                        Integer.parseInt(minHeightString, 16));
+            }
+            String maxWidthString = parser.getAttributeValue(null, "max_width");
+            if (maxWidthString != null) {
+                options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH,
+                        Integer.parseInt(maxWidthString, 16));
+            }
+            String maxHeightString = parser.getAttributeValue(null, "max_height");
+            if (maxHeightString != null) {
+                options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT,
+                        Integer.parseInt(maxHeightString, 16));
+            }
+            String categoryString = parser.getAttributeValue(null, "host_category");
+            if (categoryString != null) {
+                options.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
+                        Integer.parseInt(categoryString, 16));
+            }
+            return options;
+        }
+
+        private int countPendingUpdates(ArrayList<RestoreUpdateRecord> updates) {
+            int pending = 0;
+            final int N = updates.size();
+            for (int i = 0; i < N; i++) {
+                RestoreUpdateRecord r = updates.get(i);
+                if (!r.notified) {
+                    pending++;
+                }
+            }
+            return pending;
+        }
+
+        // Accumulate a list of updates that affect the given provider for a final
+        // coalesced notification broadcast once restore is over.
+        private class RestoreUpdateRecord {
+            public int oldId;
+            public int newId;
+            public boolean notified;
+
+            public RestoreUpdateRecord(int theOldId, int theNewId) {
+                oldId = theOldId;
+                newId = theNewId;
+                notified = false;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index d434d7a..59aef32 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -1266,10 +1266,13 @@
         ArrayList<FullBackupEntry> schedule = null;
         synchronized (mQueueLock) {
             if (mFullBackupScheduleFile.exists()) {
+                FileInputStream fstream = null;
+                BufferedInputStream bufStream = null;
+                DataInputStream in = null;
                 try {
-                    FileInputStream fstream = new FileInputStream(mFullBackupScheduleFile);
-                    BufferedInputStream bufStream = new BufferedInputStream(fstream);
-                    DataInputStream in = new DataInputStream(bufStream);
+                    fstream = new FileInputStream(mFullBackupScheduleFile);
+                    bufStream = new BufferedInputStream(fstream);
+                    in = new DataInputStream(bufStream);
 
                     int version = in.readInt();
                     if (version != SCHEDULE_FILE_VERSION) {
@@ -1289,6 +1292,10 @@
                     Slog.e(TAG, "Unable to read backup schedule", e);
                     mFullBackupScheduleFile.delete();
                     schedule = null;
+                } finally {
+                    IoUtils.closeQuietly(in);
+                    IoUtils.closeQuietly(bufStream);
+                    IoUtils.closeQuietly(fstream);
                 }
             }
 
@@ -1812,18 +1819,23 @@
         @Override
         public void onServiceConnected(ComponentName component, IBinder service) {
             if (DEBUG) Slog.v(TAG, "Connected to transport " + component);
+            final String name = component.flattenToShortString();
             try {
                 IBackupTransport transport = IBackupTransport.Stub.asInterface(service);
-                registerTransport(transport.name(), component.flattenToShortString(), transport);
+                registerTransport(transport.name(), name, transport);
+                EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_LIFECYCLE, name, 1);
             } catch (RemoteException e) {
                 Slog.e(TAG, "Unable to register transport " + component);
+                EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_LIFECYCLE, name, 0);
             }
         }
 
         @Override
         public void onServiceDisconnected(ComponentName component) {
             if (DEBUG) Slog.v(TAG, "Disconnected from transport " + component);
-            registerTransport(null, component.flattenToShortString(), null);
+            final String name = component.flattenToShortString();
+            EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_LIFECYCLE, name, 0);
+            registerTransport(null, name, null);
         }
     };
 
@@ -3683,6 +3695,9 @@
                         Slog.i(TAG, "Initiating full-data transport backup of "
                                 + currentPackage.packageName);
                     }
+                    EventLog.writeEvent(EventLogTags.FULL_BACKUP_PACKAGE,
+                            currentPackage.packageName);
+
                     transportPipes = ParcelFileDescriptor.createPipe();
 
                     // Tell the transport the data's coming
@@ -3773,12 +3788,19 @@
                                     + currentPackage.packageName
                                     + ", skipping");
                         }
+                        EventLog.writeEvent(EventLogTags.FULL_BACKUP_AGENT_FAILURE,
+                                currentPackage.packageName, "transport rejected");
                         // do nothing, clean up, and continue looping
                     } else if (result != BackupTransport.TRANSPORT_OK) {
                         if (DEBUG) {
                             Slog.i(TAG, "Transport failed; aborting backup: " + result);
+                            EventLog.writeEvent(EventLogTags.FULL_BACKUP_TRANSPORT_FAILURE);
                             return;
                         }
+                    } else {
+                        // Success!
+                        EventLog.writeEvent(EventLogTags.FULL_BACKUP_SUCCESS,
+                                currentPackage.packageName);
                     }
                     cleanUpPipes(transportPipes);
                     cleanUpPipes(enginePipes);
@@ -7332,6 +7354,9 @@
                 UnifiedRestoreState nextState = UnifiedRestoreState.RUNNING_QUEUE;
                 int status = BackupTransport.TRANSPORT_OK;
 
+                EventLog.writeEvent(EventLogTags.FULL_RESTORE_PACKAGE,
+                        mCurrentPackage.packageName);
+
                 mEngine = new FullRestoreEngine(null, mCurrentPackage, false, false);
                 EngineThread eThread = new EngineThread(mEngine, mEnginePipes[0]);
 
@@ -7383,6 +7408,7 @@
                             // handling will deal properly with that.
                             Slog.e(TAG, "Error " + result + " streaming restore for "
                                     + mCurrentPackage.packageName);
+                            EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
                             status = result;
                         }
                     }
@@ -7392,12 +7418,15 @@
                     // but potentially recoverable; abandon this package's restore but
                     // carry on with the next restore target.
                     Slog.e(TAG, "Unable to route data for restore");
+                    EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
+                            mCurrentPackage.packageName, "I/O error on pipes");
                     status = BackupTransport.AGENT_ERROR;
                 } catch (RemoteException e) {
                     // The transport went away; terminate the whole operation.  Closing
                     // the sockets will wake up the engine and it will then tidy up the
                     // remote end.
                     Slog.e(TAG, "Transport failed during restore");
+                    EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
                     status = BackupTransport.TRANSPORT_ERROR;
                 } finally {
                     // Close the transport pipes and *our* end of the engine pipe,
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 13e1b37..ef6e07c 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -437,13 +437,18 @@
 
     @Override
     public void resetAllModes() {
+        int callingUid = Binder.getCallingUid();
         mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
-                Binder.getCallingPid(), Binder.getCallingUid(), null);
+                Binder.getCallingPid(), callingUid, null);
         HashMap<Callback, ArrayList<Pair<String, Integer>>> callbacks = null;
         synchronized (this) {
             boolean changed = false;
             for (int i=mUidOps.size()-1; i>=0; i--) {
                 HashMap<String, Ops> packages = mUidOps.valueAt(i);
+                if (UserHandle.getUserId(callingUid) != UserHandle.getUserId(mUidOps.keyAt(i))) {
+                    // Skip any ops for a different user
+                    continue;
+                }
                 Iterator<Map.Entry<String, Ops>> it = packages.entrySet().iterator();
                 while (it.hasNext()) {
                     Map.Entry<String, Ops> ent = it.next();
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 5382489..6761f24 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -55,7 +55,6 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.ContentObserver;
-import android.net.CaptivePortalTracker;
 import android.net.ConnectivityManager;
 import android.net.IConnectivityManager;
 import android.net.INetworkManagementEventObserver;
@@ -248,12 +247,6 @@
      */
     private NetworkStateTracker mNetTrackers[];
 
-    /*
-     * Handles captive portal check on a network.
-     * Only set if device has {@link PackageManager#FEATURE_WIFI}.
-     */
-    private CaptivePortalTracker mCaptivePortalTracker;
-
     private Context mContext;
     private int mNetworkPreference;
     private int mActiveDefaultNetwork = -1;
@@ -465,6 +458,11 @@
      *    changes.
      */
     private class LegacyTypeTracker {
+
+        private static final boolean DBG = true;
+        private static final boolean VDBG = false;
+        private static final String TAG = "CSLegacyTypeTracker";
+
         /**
          * Array of lists, one per legacy network type (e.g., TYPE_MOBILE_MMS).
          * Each list holds references to all NetworkAgentInfos that are used to
@@ -508,6 +506,15 @@
             }
         }
 
+        private void maybeLogBroadcast(NetworkAgentInfo nai, boolean connected, int type) {
+            if (DBG) {
+                log("Sending " + (connected ? "connected" : "disconnected") +
+                        " broadcast for type " + type + " " + nai.name() +
+                        " isDefaultNetwork=" + isDefaultNetwork(nai));
+            }
+        }
+
+        /** Adds the given network to the specified legacy type list. */
         public void add(int type, NetworkAgentInfo nai) {
             if (!isTypeSupported(type)) {
                 return;  // Invalid network type.
@@ -521,42 +528,54 @@
             }
 
             if (list.isEmpty() || isDefaultNetwork(nai)) {
-                if (VDBG) log("Sending connected broadcast for type " + type +
-                              "isDefaultNetwork=" + isDefaultNetwork(nai));
+                maybeLogBroadcast(nai, true, type);
                 sendLegacyNetworkBroadcast(nai, true, type);
             }
             list.add(nai);
         }
 
+        /** Removes the given network from the specified legacy type list. */
+        public void remove(int type, NetworkAgentInfo nai) {
+            ArrayList<NetworkAgentInfo> list = mTypeLists[type];
+            if (list == null || list.isEmpty()) {
+                return;
+            }
+
+            boolean wasFirstNetwork = list.get(0).equals(nai);
+
+            if (!list.remove(nai)) {
+                return;
+            }
+
+            if (wasFirstNetwork || isDefaultNetwork(nai)) {
+                maybeLogBroadcast(nai, false, type);
+                sendLegacyNetworkBroadcast(nai, false, type);
+            }
+
+            if (!list.isEmpty() && wasFirstNetwork) {
+                if (DBG) log("Other network available for type " + type +
+                              ", sending connected broadcast");
+                maybeLogBroadcast(list.get(0), false, type);
+                sendLegacyNetworkBroadcast(list.get(0), false, type);
+            }
+        }
+
+        /** Removes the given network from all legacy type lists. */
         public void remove(NetworkAgentInfo nai) {
             if (VDBG) log("Removing agent " + nai);
             for (int type = 0; type < mTypeLists.length; type++) {
-                ArrayList<NetworkAgentInfo> list = mTypeLists[type];
-                if (list == null || list.isEmpty()) {
-                    continue;
-                }
-
-                boolean wasFirstNetwork = false;
-                if (list.get(0).equals(nai)) {
-                    // This network was the first in the list. Send broadcast.
-                    wasFirstNetwork = true;
-                }
-                list.remove(nai);
-
-                if (wasFirstNetwork || isDefaultNetwork(nai)) {
-                    if (VDBG) log("Sending disconnected broadcast for type " + type +
-                                  "isDefaultNetwork=" + isDefaultNetwork(nai));
-                    sendLegacyNetworkBroadcast(nai, false, type);
-                }
-
-                if (!list.isEmpty() && wasFirstNetwork) {
-                    if (VDBG) log("Other network available for type " + type +
-                                  ", sending connected broadcast");
-                    sendLegacyNetworkBroadcast(list.get(0), false, type);
-                }
+                remove(type, nai);
             }
         }
 
+        private String naiToString(NetworkAgentInfo nai) {
+            String name = (nai != null) ? nai.name() : "null";
+            String state = (nai.networkInfo != null) ?
+                    nai.networkInfo.getState() + "/" + nai.networkInfo.getDetailedState() :
+                    "???/???";
+            return name + " " + state;
+        }
+
         public void dump(IndentingPrintWriter pw) {
             for (int type = 0; type < mTypeLists.length; type++) {
                 if (mTypeLists[type] == null) continue;
@@ -564,11 +583,17 @@
                 pw.increaseIndent();
                 if (mTypeLists[type].size() == 0) pw.println("none");
                 for (NetworkAgentInfo nai : mTypeLists[type]) {
-                    pw.println(nai.name());
+                    pw.println(naiToString(nai));
                 }
                 pw.decreaseIndent();
             }
         }
+
+        // This class needs its own log method because it has a different TAG.
+        private void log(String s) {
+            Slog.d(TAG, s);
+        }
+
     }
     private LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker();
 
@@ -806,9 +831,11 @@
             // network is blocked; clone and override state
             info = new NetworkInfo(info);
             info.setDetailedState(DetailedState.BLOCKED, null, null);
+            if (VDBG) log("returning Blocked NetworkInfo");
         }
         if (mLockdownTracker != null) {
             info = mLockdownTracker.augmentNetworkInfo(info);
+            if (VDBG) log("returning Locked NetworkInfo");
         }
         return info;
     }
@@ -1410,9 +1437,6 @@
                 SAMPLE_INTERVAL_ELAPSED_REQUEST_CODE, intent, 0);
         setAlarm(DEFAULT_START_SAMPLING_INTERVAL_IN_SECONDS * 1000, mSampleIntervalElapsedIntent);
 
-        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) {
-            mCaptivePortalTracker = CaptivePortalTracker.makeCaptivePortalTracker(mContext, this);
-        }
         loadGlobalProxy();
 
         synchronized(this) {
@@ -1693,7 +1717,16 @@
         pw.println();
         pw.decreaseIndent();
 
-        pw.println("mActiveDefaultNetwork:" + mActiveDefaultNetwork);
+        pw.print("mActiveDefaultNetwork: " + mActiveDefaultNetwork);
+        if (mActiveDefaultNetwork != TYPE_NONE) {
+            NetworkInfo activeNetworkInfo = getActiveNetworkInfo();
+            if (activeNetworkInfo != null) {
+                pw.print(" " + activeNetworkInfo.getState() +
+                         "/" + activeNetworkInfo.getDetailedState());
+            }
+        }
+        pw.println();
+
         pw.println("mLegacyTypeTracker:");
         pw.increaseIndent();
         mLegacyTypeTracker.dump(pw);
@@ -1757,12 +1790,15 @@
                     if (nai == null) {
                         loge("NetworkAgent not found for EVENT_NETWORK_PROPERTIES_CHANGED");
                     } else {
-                        if (VDBG) log("Update of Linkproperties for " + nai.name());
+                        if (VDBG) {
+                            log("Update of Linkproperties for " + nai.name() +
+                                    "; created=" + nai.created);
+                        }
                         LinkProperties oldLp = nai.linkProperties;
                         synchronized (nai) {
                             nai.linkProperties = (LinkProperties)msg.obj;
                         }
-                        updateLinkProperties(nai, oldLp);
+                        if (nai.created) updateLinkProperties(nai, oldLp);
                     }
                     break;
                 }
@@ -1986,6 +2022,7 @@
                     synchronized (mNetworkForNetId) {
                         mNetworkForNetId.remove(nai.network.netId);
                     }
+                    // Just in case.
                     mLegacyTypeTracker.remove(nai);
                 }
             }
@@ -1998,12 +2035,14 @@
                 log(nai.name() + " got DISCONNECTED, was satisfying " + nai.networkRequests.size());
             }
             // A network agent has disconnected.
-            // Tell netd to clean up the configuration for this network
-            // (routing rules, DNS, etc).
-            try {
-                mNetd.removeNetwork(nai.network.netId);
-            } catch (Exception e) {
-                loge("Exception removing network: " + e);
+            if (nai.created) {
+                // Tell netd to clean up the configuration for this network
+                // (routing rules, DNS, etc).
+                try {
+                    mNetd.removeNetwork(nai.network.netId);
+                } catch (Exception e) {
+                    loge("Exception removing network: " + e);
+                }
             }
             // TODO - if we move the logic to the network agent (have them disconnect
             // because they lost all their requests or because their score isn't good)
@@ -2087,15 +2126,14 @@
             }
             bestNetwork.addRequest(nri.request);
             mNetworkForRequestId.put(nri.request.requestId, bestNetwork);
-            int legacyType = nri.request.legacyType;
-            if (legacyType != TYPE_NONE) {
-                mLegacyTypeTracker.add(legacyType, bestNetwork);
-            }
             notifyNetworkCallback(bestNetwork, nri);
             score = bestNetwork.currentScore;
+            if (nri.isRequest && nri.request.legacyType != TYPE_NONE) {
+                mLegacyTypeTracker.add(nri.request.legacyType, bestNetwork);
+            }
         }
         mNetworkRequests.put(nri.request, nri);
-        if (msg.what == EVENT_REGISTER_NETWORK_REQUEST) {
+        if (nri.isRequest) {
             if (DBG) log("sending new NetworkRequest to factories");
             for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
                 nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score,
@@ -2123,6 +2161,9 @@
                     log(" Removing from current network " + affectedNetwork.name() + ", leaving " +
                             affectedNetwork.networkRequests.size() + " requests.");
                 }
+                if (nri.isRequest && nri.request.legacyType != TYPE_NONE) {
+                    mLegacyTypeTracker.remove(nri.request.legacyType, affectedNetwork);
+                }
             }
 
             if (nri.isRequest) {
@@ -4200,8 +4241,8 @@
 //        for (LinkProperties lp : newLp.getStackedLinks()) {
 //            updateMtu(lp, null);
 //        }
-        updateRoutes(newLp, oldLp, netId);
-        updateDnses(newLp, oldLp, netId);
+        final boolean flushDns = updateRoutes(newLp, oldLp, netId);
+        updateDnses(newLp, oldLp, netId, flushDns);
         updateClat(newLp, oldLp, networkAgent);
     }
 
@@ -4249,7 +4290,11 @@
         }
     }
 
-    private void updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) {
+    /**
+     * Have netd update routes from oldLp to newLp.
+     * @return true if routes changed between oldLp and newLp
+     */
+    private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) {
         CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>();
         if (oldLp != null) {
             routeDiff = oldLp.compareAllRoutes(newLp);
@@ -4284,8 +4329,9 @@
                 loge("Exception in removeRoute: " + e);
             }
         }
+        return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty();
     }
-    private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) {
+    private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId, boolean flush) {
         if (oldLp == null || (newLp.isIdenticalDnses(oldLp) == false)) {
             Collection<InetAddress> dnses = newLp.getDnsServers();
             if (dnses.size() == 0 && mDefaultDns != null) {
@@ -4306,6 +4352,13 @@
                 setDefaultDnsSystemProperties(dnses);
             }
             flushVmDnsCache();
+        } else if (flush) {
+            try {
+                mNetd.flushNetworkDnsCache(netId);
+            } catch (Exception e) {
+                loge("Exception in flushNetworkDnsCache: " + e);
+            }
+            flushVmDnsCache();
         }
     }
 
@@ -4454,9 +4507,8 @@
                     }
                     mNetworkForRequestId.put(nri.request.requestId, newNetwork);
                     newNetwork.addRequest(nri.request);
-                    int legacyType = nri.request.legacyType;
-                    if (legacyType != TYPE_NONE) {
-                        mLegacyTypeTracker.add(legacyType, newNetwork);
+                    if (nri.isRequest && nri.request.legacyType != TYPE_NONE) {
+                        mLegacyTypeTracker.add(nri.request.legacyType, newNetwork);
                     }
                     keep = true;
                     // TODO - this could get expensive if we have alot of requests for this
@@ -4472,6 +4524,14 @@
                         } else {
                             setDefaultDnsSystemProperties(new ArrayList<InetAddress>());
                         }
+                        // Maintain the illusion: since the legacy API only
+                        // understands one network at a time, we must pretend
+                        // that the current default network disconnected before
+                        // the new one connected.
+                        if (currentNetwork != null) {
+                            mLegacyTypeTracker.remove(currentNetwork.networkInfo.getType(),
+                                                      currentNetwork);
+                        }
                         mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork);
                     }
                 }
@@ -4567,13 +4627,9 @@
                     " to " + state);
         }
 
-        if (state == NetworkInfo.State.CONNECTED) {
+        if (state == NetworkInfo.State.CONNECTED && !networkAgent.created) {
             try {
-                // This is likely caused by the fact that this network already
-                // exists. An example is when a network goes from CONNECTED to
-                // CONNECTING and back (like wifi on DHCP renew).
-                // TODO: keep track of which networks we've created, or ask netd
-                // to tell us whether we've already created this network or not.
+                // This should never fail.  Specifying an already in use NetID will cause failure.
                 if (networkAgent.isVPN()) {
                     mNetd.createVirtualNetwork(networkAgent.network.netId,
                             !networkAgent.linkProperties.getDnsServers().isEmpty(),
@@ -4587,7 +4643,7 @@
                         + e.getMessage());
                 return;
             }
-
+            networkAgent.created = true;
             updateLinkProperties(networkAgent, null);
             notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK);
             networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
@@ -4665,13 +4721,19 @@
     }
 
     private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, boolean connected, int type) {
+        // The NetworkInfo we actually send out has no bearing on the real
+        // state of affairs. For example, if the default connection is mobile,
+        // and a request for HIPRI has just gone away, we need to pretend that
+        // HIPRI has just disconnected. So we need to set the type to HIPRI and
+        // the state to DISCONNECTED, even though the network is of type MOBILE
+        // and is still connected.
+        NetworkInfo info = new NetworkInfo(nai.networkInfo);
+        info.setType(type);
         if (connected) {
-            NetworkInfo info = new NetworkInfo(nai.networkInfo);
-            info.setType(type);
+            info.setDetailedState(DetailedState.CONNECTED, null, info.getExtraInfo());
             sendConnectedBroadcastDelayed(info, getConnectivityChangeDelay());
         } else {
-            NetworkInfo info = new NetworkInfo(nai.networkInfo);
-            info.setType(type);
+            info.setDetailedState(DetailedState.DISCONNECTED, null, info.getExtraInfo());
             Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 3c50947..5aaeb6a 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -102,6 +102,14 @@
 2833 restore_package (Package|3),(Size|1|2)
 2834 restore_success (Packages|1|1),(Time|1|3)
 
+2840 full_backup_package (Package|3)
+2841 full_backup_agent_failure (Package|3),(Message|3)
+2842 full_backup_transport_failure
+2843 full_backup_success (Package|3)
+2844 full_restore_package (Package|3)
+
+2850 backup_transport_lifecycle (Transport|3),(Bound|1|1)
+
 
 # ---------------------------
 # SystemServer.java
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index d4f141d..4687e3f 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -51,6 +51,7 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnCancelListener;
+import android.content.DialogInterface.OnClickListener;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
@@ -91,6 +92,7 @@
 import android.util.Printer;
 import android.util.Slog;
 import android.util.Xml;
+import android.view.ContextThemeWrapper;
 import android.view.IWindowManager;
 import android.view.InputChannel;
 import android.view.LayoutInflater;
@@ -202,7 +204,7 @@
     private boolean mNotificationShown;
     private final boolean mImeSelectedOnBoot;
 
-    class SessionState {
+    static class SessionState {
         final ClientState client;
         final IInputMethod method;
 
@@ -2728,6 +2730,7 @@
         return mKeyguardManager != null
                 && mKeyguardManager.isKeyguardLocked() && mKeyguardManager.isKeyguardSecure();
     }
+
     private void showInputMethodMenuInternal(boolean showSubtypes) {
         if (DEBUG) Slog.v(TAG, "Show switching menu");
 
@@ -2778,84 +2781,81 @@
                     }
                 }
             }
-            final TypedArray a = context.obtainStyledAttributes(null,
+            final Context themedContext = new ContextThemeWrapper(context,
+                    android.R.style.Theme_DeviceDefault_Settings);
+            mDialogBuilder = new AlertDialog.Builder(themedContext);
+            final TypedArray a = themedContext.obtainStyledAttributes(null,
                     com.android.internal.R.styleable.DialogPreference,
                     com.android.internal.R.attr.alertDialogStyle, 0);
-            mDialogBuilder = new AlertDialog.Builder(context)
-                    .setOnCancelListener(new OnCancelListener() {
-                        @Override
-                        public void onCancel(DialogInterface dialog) {
-                            hideInputMethodMenu();
-                        }
-                    })
-                    .setIcon(a.getDrawable(
-                            com.android.internal.R.styleable.DialogPreference_dialogTitle));
+            mDialogBuilder.setIcon(a.getDrawable(
+                    com.android.internal.R.styleable.DialogPreference_dialogIcon));
             a.recycle();
+            mDialogBuilder.setOnCancelListener(new OnCancelListener() {
+                @Override
+                public void onCancel(DialogInterface dialog) {
+                    hideInputMethodMenu();
+                }
+            });
             final LayoutInflater inflater =
-                    (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+                    (LayoutInflater)themedContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
             final View tv = inflater.inflate(
                     com.android.internal.R.layout.input_method_switch_dialog_title, null);
             mDialogBuilder.setCustomTitle(tv);
 
             // Setup layout for a toggle switch of the hardware keyboard
             mSwitchingDialogTitleView = tv;
-            mSwitchingDialogTitleView.findViewById(
-                    com.android.internal.R.id.hard_keyboard_section).setVisibility(
-                            mWindowManagerService.isHardKeyboardAvailable() ?
-                                    View.VISIBLE : View.GONE);
-            final Switch hardKeySwitch =  ((Switch)mSwitchingDialogTitleView.findViewById(
-                    com.android.internal.R.id.hard_keyboard_switch));
+            mSwitchingDialogTitleView
+                    .findViewById(com.android.internal.R.id.hard_keyboard_section)
+                    .setVisibility(mWindowManagerService.isHardKeyboardAvailable()
+                            ? View.VISIBLE : View.GONE);
+            final Switch hardKeySwitch = (Switch)mSwitchingDialogTitleView.findViewById(
+                    com.android.internal.R.id.hard_keyboard_switch);
             hardKeySwitch.setChecked(mWindowManagerService.isHardKeyboardEnabled());
-            hardKeySwitch.setOnCheckedChangeListener(
-                    new OnCheckedChangeListener() {
-                        @Override
-                        public void onCheckedChanged(
-                                CompoundButton buttonView, boolean isChecked) {
-                            mWindowManagerService.setHardKeyboardEnabled(isChecked);
-                            // Ensure that the input method dialog is dismissed when changing
-                            // the hardware keyboard state.
-                            hideInputMethodMenu();
+            hardKeySwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+                @Override
+                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                    mWindowManagerService.setHardKeyboardEnabled(isChecked);
+                    // Ensure that the input method dialog is dismissed when changing
+                    // the hardware keyboard state.
+                    hideInputMethodMenu();
+                }
+            });
+
+            final ImeSubtypeListAdapter adapter = new ImeSubtypeListAdapter(themedContext,
+                    com.android.internal.R.layout.input_method_switch_item, imList, checkedItem);
+            final OnClickListener choiceListener = new OnClickListener() {
+                @Override
+                public void onClick(final DialogInterface dialog, final int which) {
+                    synchronized (mMethodMap) {
+                        if (mIms == null || mIms.length <= which || mSubtypeIds == null
+                                || mSubtypeIds.length <= which) {
+                            return;
                         }
-                    });
-
-            final ImeSubtypeListAdapter adapter = new ImeSubtypeListAdapter(context,
-                    com.android.internal.R.layout.simple_list_item_2_single_choice, imList,
-                    checkedItem);
-
-            mDialogBuilder.setSingleChoiceItems(adapter, checkedItem,
-                    new AlertDialog.OnClickListener() {
-                        @Override
-                        public void onClick(DialogInterface dialog, int which) {
-                            synchronized (mMethodMap) {
-                                if (mIms == null || mIms.length <= which
-                                        || mSubtypeIds == null || mSubtypeIds.length <= which) {
-                                    return;
-                                }
-                                InputMethodInfo im = mIms[which];
-                                int subtypeId = mSubtypeIds[which];
-                                adapter.mCheckedItem = which;
-                                adapter.notifyDataSetChanged();
-                                hideInputMethodMenu();
-                                if (im != null) {
-                                    if ((subtypeId < 0)
-                                            || (subtypeId >= im.getSubtypeCount())) {
-                                        subtypeId = NOT_A_SUBTYPE_ID;
-                                    }
-                                    setInputMethodLocked(im.getId(), subtypeId);
-                                }
+                        final InputMethodInfo im = mIms[which];
+                        int subtypeId = mSubtypeIds[which];
+                        adapter.mCheckedItem = which;
+                        adapter.notifyDataSetChanged();
+                        hideInputMethodMenu();
+                        if (im != null) {
+                            if (subtypeId < 0 || subtypeId >= im.getSubtypeCount()) {
+                                subtypeId = NOT_A_SUBTYPE_ID;
                             }
+                            setInputMethodLocked(im.getId(), subtypeId);
                         }
-                    });
+                    }
+                }
+            };
+            mDialogBuilder.setSingleChoiceItems(adapter, checkedItem, choiceListener);
 
             if (showSubtypes && !isScreenLocked) {
+                final OnClickListener positiveListener = new OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int whichButton) {
+                        showConfigureInputMethods();
+                    }
+                };
                 mDialogBuilder.setPositiveButton(
-                        com.android.internal.R.string.configure_input_methods,
-                        new DialogInterface.OnClickListener() {
-                            @Override
-                            public void onClick(DialogInterface dialog, int whichButton) {
-                                showConfigureInputMethods();
-                            }
-                        });
+                        com.android.internal.R.string.configure_input_methods, positiveListener);
             }
             mSwitchingDialog = mDialogBuilder.create();
             mSwitchingDialog.setCanceledOnTouchOutside(true);
diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java
index 2fad73e..df54c7f 100644
--- a/services/core/java/com/android/server/MmsServiceBroker.java
+++ b/services/core/java/com/android/server/MmsServiceBroker.java
@@ -49,6 +49,11 @@
 
     private static final int MSG_TRY_CONNECTING = 1;
 
+    private static final Uri FAKE_SMS_SENT_URI = Uri.parse("content://sms/sent/0");
+    private static final Uri FAKE_MMS_SENT_URI = Uri.parse("content://mms/sent/0");
+    private static final Uri FAKE_SMS_DRAFT_URI = Uri.parse("content://sms/draft/0");
+    private static final Uri FAKE_MMS_DRAFT_URI = Uri.parse("content://mms/draft/0");
+
     private Context mContext;
     // The actual MMS service instance to invoke
     private volatile IMms mService;
@@ -186,25 +191,28 @@
     private final class BinderService extends IMms.Stub {
         @Override
         public void sendMessage(long subId, String callingPkg, byte[] pdu, String locationUrl,
-                PendingIntent sentIntent) throws RemoteException {
+                ContentValues configOverrides, PendingIntent sentIntent) throws RemoteException {
             mContext.enforceCallingPermission(Manifest.permission.SEND_SMS, "Send MMS message");
             if (getAppOpsManager().noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
                     callingPkg) != AppOpsManager.MODE_ALLOWED) {
                 return;
             }
-            getServiceGuarded().sendMessage(subId, callingPkg, pdu, locationUrl, sentIntent);
+            getServiceGuarded().sendMessage(subId, callingPkg, pdu, locationUrl, configOverrides,
+                    sentIntent);
         }
 
         @Override
         public void downloadMessage(long subId, String callingPkg, String locationUrl,
-                PendingIntent downloadedIntent) throws RemoteException {
+                ContentValues configOverrides, PendingIntent downloadedIntent)
+                throws RemoteException {
             mContext.enforceCallingPermission(Manifest.permission.RECEIVE_MMS,
                     "Download MMS message");
             if (getAppOpsManager().noteOp(AppOpsManager.OP_RECEIVE_MMS, Binder.getCallingUid(),
                     callingPkg) != AppOpsManager.MODE_ALLOWED) {
                 return;
             }
-            getServiceGuarded().downloadMessage(subId, callingPkg, locationUrl, downloadedIntent);
+            getServiceGuarded().downloadMessage(subId, callingPkg, locationUrl, configOverrides,
+                    downloadedIntent);
         }
 
         @Override
@@ -220,53 +228,21 @@
         }
 
         @Override
-        public boolean getCarrierConfigBoolean(String name, boolean defaultValue)
+        public boolean getCarrierConfigBoolean(long subId, String name, boolean defaultValue)
                 throws RemoteException {
-            return getServiceGuarded().getCarrierConfigBoolean(name, defaultValue);
+            return getServiceGuarded().getCarrierConfigBoolean(subId, name, defaultValue);
         }
 
         @Override
-        public int getCarrierConfigInt(String name, int defaultValue) throws RemoteException {
-            return getServiceGuarded().getCarrierConfigInt(name, defaultValue);
+        public int getCarrierConfigInt(long subId, String name, int defaultValue)
+                throws RemoteException {
+            return getServiceGuarded().getCarrierConfigInt(subId, name, defaultValue);
         }
 
         @Override
-        public String getCarrierConfigString(String name, String defaultValue)
+        public String getCarrierConfigString(long subId, String name, String defaultValue)
                 throws RemoteException {
-            return getServiceGuarded().getCarrierConfigString(name, defaultValue);
-        }
-
-        @Override
-        public void setCarrierConfigBoolean(String callingPkg, String name, boolean value)
-                throws RemoteException {
-            mContext.enforceCallingPermission(Manifest.permission.SEND_SMS, "Set MMS config");
-            if (getAppOpsManager().noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
-                    callingPkg) != AppOpsManager.MODE_ALLOWED) {
-                return;
-            }
-            getServiceGuarded().setCarrierConfigBoolean(callingPkg, name, value);
-        }
-
-        @Override
-        public void setCarrierConfigInt(String callingPkg, String name, int value)
-                throws RemoteException {
-            mContext.enforceCallingPermission(Manifest.permission.SEND_SMS, "Set MMS config");
-            if (getAppOpsManager().noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
-                    callingPkg) != AppOpsManager.MODE_ALLOWED) {
-                return;
-            }
-            getServiceGuarded().setCarrierConfigInt(callingPkg, name, value);
-        }
-
-        @Override
-        public void setCarrierConfigString(String callingPkg, String name, String value)
-                throws RemoteException {
-            mContext.enforceCallingPermission(Manifest.permission.SEND_SMS, "Set MMS config");
-            if (getAppOpsManager().noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
-                    callingPkg) != AppOpsManager.MODE_ALLOWED) {
-                return;
-            }
-            getServiceGuarded().setCarrierConfigString(callingPkg, name, value);
+            return getServiceGuarded().getCarrierConfigString(subId, name, defaultValue);
         }
 
         @Override
@@ -275,7 +251,9 @@
             mContext.enforceCallingPermission(Manifest.permission.WRITE_SMS, "Import SMS message");
             if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SMS, Binder.getCallingUid(),
                     callingPkg) != AppOpsManager.MODE_ALLOWED) {
-                return null;
+                // Silently fail AppOps failure due to not being the default SMS app
+                // while writing the TelephonyProvider
+                return FAKE_SMS_SENT_URI;
             }
             return getServiceGuarded().importTextMessage(
                     callingPkg, address, type, text, timestampMillis, seen, read);
@@ -287,7 +265,9 @@
             mContext.enforceCallingPermission(Manifest.permission.WRITE_SMS, "Import MMS message");
             if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SMS, Binder.getCallingUid(),
                     callingPkg) != AppOpsManager.MODE_ALLOWED) {
-                return null;
+                // Silently fail AppOps failure due to not being the default SMS app
+                // while writing the TelephonyProvider
+                return FAKE_MMS_SENT_URI;
             }
             return getServiceGuarded().importMultimediaMessage(
                     callingPkg, pdu, messageId, timestampSecs, seen, read);
@@ -340,7 +320,9 @@
             mContext.enforceCallingPermission(Manifest.permission.WRITE_SMS, "Add SMS draft");
             if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SMS, Binder.getCallingUid(),
                     callingPkg) != AppOpsManager.MODE_ALLOWED) {
-                return null;
+                // Silently fail AppOps failure due to not being the default SMS app
+                // while writing the TelephonyProvider
+                return FAKE_SMS_DRAFT_URI;
             }
             return getServiceGuarded().addTextMessageDraft(callingPkg, address, text);
         }
@@ -350,21 +332,24 @@
             mContext.enforceCallingPermission(Manifest.permission.WRITE_SMS, "Add MMS draft");
             if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SMS, Binder.getCallingUid(),
                     callingPkg) != AppOpsManager.MODE_ALLOWED) {
-                return null;
+                // Silently fail AppOps failure due to not being the default SMS app
+                // while writing the TelephonyProvider
+                return FAKE_MMS_DRAFT_URI;
             }
             return getServiceGuarded().addMultimediaMessageDraft(callingPkg, pdu);
         }
 
         @Override
         public void sendStoredMessage(long subId, String callingPkg, Uri messageUri,
-                PendingIntent sentIntent) throws RemoteException {
+                ContentValues configOverrides, PendingIntent sentIntent) throws RemoteException {
             mContext.enforceCallingPermission(Manifest.permission.SEND_SMS,
                     "Send stored MMS message");
             if (getAppOpsManager().noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
                     callingPkg) != AppOpsManager.MODE_ALLOWED) {
                 return;
             }
-            getServiceGuarded().sendStoredMessage(subId, callingPkg, messageUri, sentIntent);
+            getServiceGuarded().sendStoredMessage(subId, callingPkg, messageUri, configOverrides,
+                    sentIntent);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 362a745..f9b65b8 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -1748,6 +1748,16 @@
     }
 
     @Override
+    public void flushNetworkDnsCache(int netId) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.execute("resolver", "flushnet", netId);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
     public void setFirewallEnabled(boolean enabled) {
         enforceSystemUid();
         try {
diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java
index f71a18a..2896f60 100644
--- a/services/core/java/com/android/server/PersistentDataBlockService.java
+++ b/services/core/java/com/android/server/PersistentDataBlockService.java
@@ -23,6 +23,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.SystemProperties;
+import android.os.UserHandle;
 import android.service.persistentdata.IPersistentDataBlockService;
 import android.util.Slog;
 import com.android.internal.R;
@@ -66,8 +67,9 @@
 
     private final Context mContext;
     private final String mDataBlockFile;
-    private final int mAllowedUid;
     private final Object mLock = new Object();
+
+    private int mAllowedAppId = -1;
     /*
      * Separate lock for OEM unlock related operations as they can happen in parallel with regular
      * block operations.
@@ -81,19 +83,22 @@
         mContext = context;
         mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP);
         mBlockDeviceSize = -1; // Load lazily
-        String allowedPackage = context.getResources()
+        mAllowedAppId = getAllowedAppId(UserHandle.USER_OWNER);
+    }
+
+
+    private int getAllowedAppId(int userHandle) {
+        String allowedPackage = mContext.getResources()
                 .getString(R.string.config_persistentDataPackageName);
         PackageManager pm = mContext.getPackageManager();
         int allowedUid = -1;
         try {
-            allowedUid = pm.getPackageUid(allowedPackage,
-                    Binder.getCallingUserHandle().getIdentifier());
+            allowedUid = pm.getPackageUid(allowedPackage, userHandle);
         } catch (PackageManager.NameNotFoundException e) {
             // not expected
             Slog.e(TAG, "not able to find package " + allowedPackage, e);
         }
-
-        mAllowedUid = allowedUid;
+        return UserHandle.getAppId(allowedUid);
     }
 
     @Override
@@ -108,7 +113,7 @@
     }
 
     private void enforceUid(int callingUid) {
-        if (callingUid != mAllowedUid) {
+        if (UserHandle.getAppId(callingUid) != mAllowedAppId) {
             throw new SecurityException("uid " + callingUid + " not allowed to access PST");
         }
     }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index cb410ef..7624314 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -80,9 +80,9 @@
  */
 class TelephonyRegistry extends ITelephonyRegistry.Stub {
     private static final String TAG = "TelephonyRegistry";
-    private static final boolean DBG = true; // STOPSHIP if true
+    private static final boolean DBG = false; // STOPSHIP if true
     private static final boolean DBG_LOC = false; // STOPSHIP if true
-    private static final boolean VDBG = true; // STOPSHIP if true
+    private static final boolean VDBG = false; // STOPSHIP if true
 
     private static class Record {
         String pkgForDebug;
diff --git a/services/core/java/com/android/server/WiredAccessoryManager.java b/services/core/java/com/android/server/WiredAccessoryManager.java
index d8ee8a1..bffbb4c2 100644
--- a/services/core/java/com/android/server/WiredAccessoryManager.java
+++ b/services/core/java/com/android/server/WiredAccessoryManager.java
@@ -36,8 +36,10 @@
 import com.android.server.input.InputManagerService.WiredAccessoryCallbacks;
 import static com.android.server.input.InputManagerService.SW_HEADPHONE_INSERT;
 import static com.android.server.input.InputManagerService.SW_MICROPHONE_INSERT;
+import static com.android.server.input.InputManagerService.SW_LINEOUT_INSERT;
 import static com.android.server.input.InputManagerService.SW_HEADPHONE_INSERT_BIT;
 import static com.android.server.input.InputManagerService.SW_MICROPHONE_INSERT_BIT;
+import static com.android.server.input.InputManagerService.SW_LINEOUT_INSERT_BIT;
 
 import java.io.File;
 import java.io.FileReader;
@@ -60,9 +62,10 @@
     private static final int BIT_USB_HEADSET_ANLG = (1 << 2);
     private static final int BIT_USB_HEADSET_DGTL = (1 << 3);
     private static final int BIT_HDMI_AUDIO = (1 << 4);
+    private static final int BIT_LINEOUT = (1 << 5);
     private static final int SUPPORTED_HEADSETS = (BIT_HEADSET|BIT_HEADSET_NO_MIC|
                                                    BIT_USB_HEADSET_ANLG|BIT_USB_HEADSET_DGTL|
-                                                   BIT_HDMI_AUDIO);
+                                                   BIT_HDMI_AUDIO|BIT_LINEOUT);
 
     private static final String NAME_H2W = "h2w";
     private static final String NAME_USB_AUDIO = "usb_audio";
@@ -108,8 +111,11 @@
             if (mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, SW_MICROPHONE_INSERT) == 1) {
                 switchValues |= SW_MICROPHONE_INSERT_BIT;
             }
+            if (mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, SW_LINEOUT_INSERT) == 1) {
+                switchValues |= SW_LINEOUT_INSERT_BIT;
+            }
             notifyWiredAccessoryChanged(0, switchValues,
-                    SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT);
+                    SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_LINEOUT_INSERT_BIT);
         }
 
         mObserver.init();
@@ -124,7 +130,8 @@
         synchronized (mLock) {
             int headset;
             mSwitchValues = (mSwitchValues & ~switchMask) | switchValues;
-            switch (mSwitchValues & (SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT)) {
+            switch (mSwitchValues &
+                (SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_LINEOUT_INSERT_BIT)) {
                 case 0:
                     headset = 0;
                     break;
@@ -133,6 +140,10 @@
                     headset = BIT_HEADSET_NO_MIC;
                     break;
 
+                case SW_LINEOUT_INSERT_BIT:
+                    headset = BIT_LINEOUT;
+                    break;
+
                 case SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT:
                     headset = BIT_HEADSET;
                     break;
@@ -146,7 +157,8 @@
                     break;
             }
 
-            updateLocked(NAME_H2W, (mHeadsetState & ~(BIT_HEADSET | BIT_HEADSET_NO_MIC)) | headset);
+            updateLocked(NAME_H2W,
+                (mHeadsetState & ~(BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_LINEOUT)) | headset);
         }
     }
 
@@ -174,7 +186,7 @@
         int headsetState = newState & SUPPORTED_HEADSETS;
         int usb_headset_anlg = headsetState & BIT_USB_HEADSET_ANLG;
         int usb_headset_dgtl = headsetState & BIT_USB_HEADSET_DGTL;
-        int h2w_headset = headsetState & (BIT_HEADSET | BIT_HEADSET_NO_MIC);
+        int h2w_headset = headsetState & (BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_LINEOUT);
         boolean h2wStateChange = true;
         boolean usbStateChange = true;
         if (LOG) Slog.v(TAG, "newName=" + newName
@@ -190,7 +202,7 @@
         // reject all suspect transitions: only accept state changes from:
         // - a: 0 headset to 1 headset
         // - b: 1 headset to 0 headset
-        if (h2w_headset == (BIT_HEADSET | BIT_HEADSET_NO_MIC)) {
+        if (h2w_headset == (BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_LINEOUT)) {
             Log.e(TAG, "Invalid combination, unsetting h2w flag");
             h2wStateChange = false;
         }
@@ -261,6 +273,8 @@
                 inDevice = AudioManager.DEVICE_IN_WIRED_HEADSET;
             } else if (headset == BIT_HEADSET_NO_MIC){
                 outDevice = AudioManager.DEVICE_OUT_WIRED_HEADPHONE;
+            } else if (headset == BIT_LINEOUT){
+                outDevice = AudioManager.DEVICE_OUT_LINE;
             } else if (headset == BIT_USB_HEADSET_ANLG) {
                 outDevice = AudioManager.DEVICE_OUT_ANLG_DOCK_HEADSET;
             } else if (headset == BIT_USB_HEADSET_DGTL) {
@@ -345,7 +359,7 @@
 
             // Monitor h2w
             if (!mUseDevInputEventForAudioJack) {
-                uei = new UEventInfo(NAME_H2W, BIT_HEADSET, BIT_HEADSET_NO_MIC);
+                uei = new UEventInfo(NAME_H2W, BIT_HEADSET, BIT_HEADSET_NO_MIC, BIT_LINEOUT);
                 if (uei.checkSwitchExists()) {
                     retVal.add(uei);
                 } else {
@@ -354,7 +368,7 @@
             }
 
             // Monitor USB
-            uei = new UEventInfo(NAME_USB_AUDIO, BIT_USB_HEADSET_ANLG, BIT_USB_HEADSET_DGTL);
+            uei = new UEventInfo(NAME_USB_AUDIO, BIT_USB_HEADSET_ANLG, BIT_USB_HEADSET_DGTL, 0);
             if (uei.checkSwitchExists()) {
                 retVal.add(uei);
             } else {
@@ -369,11 +383,11 @@
             //
             // If the kernel does not have an "hdmi_audio" switch, just fall back on the older
             // "hdmi" switch instead.
-            uei = new UEventInfo(NAME_HDMI_AUDIO, BIT_HDMI_AUDIO, 0);
+            uei = new UEventInfo(NAME_HDMI_AUDIO, BIT_HDMI_AUDIO, 0, 0);
             if (uei.checkSwitchExists()) {
                 retVal.add(uei);
             } else {
-                uei = new UEventInfo(NAME_HDMI, BIT_HDMI_AUDIO, 0);
+                uei = new UEventInfo(NAME_HDMI, BIT_HDMI_AUDIO, 0, 0);
                 if (uei.checkSwitchExists()) {
                     retVal.add(uei);
                 } else {
@@ -414,11 +428,13 @@
             private final String mDevName;
             private final int mState1Bits;
             private final int mState2Bits;
+            private final int mStateNbits;
 
-            public UEventInfo(String devName, int state1Bits, int state2Bits) {
+            public UEventInfo(String devName, int state1Bits, int state2Bits, int stateNbits) {
                 mDevName = devName;
                 mState1Bits = state1Bits;
                 mState2Bits = state2Bits;
+                mStateNbits = stateNbits;
             }
 
             public String getDevName() { return mDevName; }
@@ -437,9 +453,10 @@
             }
 
             public int computeNewHeadsetState(int headsetState, int switchState) {
-                int preserveMask = ~(mState1Bits | mState2Bits);
+                int preserveMask = ~(mState1Bits | mState2Bits | mStateNbits);
                 int setBits = ((switchState == 1) ? mState1Bits :
-                              ((switchState == 2) ? mState2Bits : 0));
+                              ((switchState == 2) ? mState2Bits :
+                              ((switchState == mStateNbits) ? mStateNbits : 0)));
 
                 return ((headsetState & preserveMask) | setBits);
             }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 9a58c56..07ad9e4 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1206,9 +1206,13 @@
                         }
                         return;
                     }
-                    if (!showBackground && UserHandle.getAppId(proc.uid)
-                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
-                            && proc.pid != MY_PID) {
+                    boolean isBackground = (UserHandle.getAppId(proc.uid)
+                            >= Process.FIRST_APPLICATION_UID
+                            && proc.pid != MY_PID);
+                    for (int userId : mCurrentProfileIds) {
+                        isBackground &= (proc.userId != userId);
+                    }
+                    if (isBackground && !showBackground) {
                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
                         if (res != null) {
                             res.set(0);
@@ -2030,7 +2034,7 @@
             mSystemThread.installSystemApplicationInfo(info);
 
             synchronized (this) {
-                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
+                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
                 app.persistent = true;
                 app.pid = MY_PID;
                 app.maxAdj = ProcessList.SYSTEM_ADJ;
@@ -2830,10 +2834,45 @@
                 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
     }
 
+    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
+            String processName, String abiOverride, int uid, Runnable crashHandler) {
+        synchronized(this) {
+            ApplicationInfo info = new ApplicationInfo();
+            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
+            // For isolated processes, the former contains the parent's uid and the latter the
+            // actual uid of the isolated process.
+            // In the special case introduced by this method (which is, starting an isolated
+            // process directly from the SystemServer without an actual parent app process) the
+            // closest thing to a parent's uid is SYSTEM_UID.
+            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
+            // the |isolated| logic in the ProcessRecord constructor.
+            info.uid = Process.SYSTEM_UID;
+            info.processName = processName;
+            info.className = entryPoint;
+            info.packageName = "android";
+            ProcessRecord proc = startProcessLocked(processName, info /* info */,
+                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
+                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
+                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
+                    crashHandler);
+            return proc != null ? proc.pid : 0;
+        }
+    }
+
     final ProcessRecord startProcessLocked(String processName,
             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
             boolean isolated, boolean keepIfLarge) {
+        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
+                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
+                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
+                null /* crashHandler */);
+    }
+
+    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
+            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
+            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
+            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
         ProcessRecord app;
         if (!isolated) {
             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
@@ -2901,7 +2940,8 @@
         }
 
         if (app == null) {
-            app = newProcessRecordLocked(info, processName, isolated);
+            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
+            app.crashHandler = crashHandler;
             if (app == null) {
                 Slog.w(TAG, "Failed making new process record for "
                         + processName + "/" + info.uid + " isolated=" + isolated);
@@ -2928,7 +2968,8 @@
             return app;
         }
 
-        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
+        startProcessLocked(
+                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
         return (app.pid != 0) ? app : null;
     }
 
@@ -2937,7 +2978,13 @@
     }
 
     private final void startProcessLocked(ProcessRecord app,
-            String hostingType, String hostingNameStr, String abiOverride) {
+            String hostingType, String hostingNameStr) {
+        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
+                null /* entryPoint */, null /* entryPointArgs */);
+    }
+
+    private final void startProcessLocked(ProcessRecord app, String hostingType,
+            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
         if (app.pid > 0 && app.pid != MY_PID) {
             synchronized (mPidsSelfLocked) {
                 mPidsSelfLocked.remove(app.pid);
@@ -3030,9 +3077,11 @@
 
             // Start the process.  It will either succeed and return a result containing
             // the PID of the new process, or else throw a RuntimeException.
-            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
+            boolean isActivityProcess = (entryPoint == null);
+            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
+            Process.ProcessStartResult startResult = Process.start(entryPoint,
                     app.processName, uid, uid, gids, debugFlags, mountExternal,
-                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
+                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
 
             if (app.isolated) {
                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
@@ -3052,6 +3101,11 @@
             buf.setLength(0);
             buf.append("Start proc ");
             buf.append(app.processName);
+            if (!isActivityProcess) {
+                buf.append(" [");
+                buf.append(entryPoint);
+                buf.append("]");
+            }
             buf.append(" for ");
             buf.append(hostingType);
             if (hostingNameStr != null) {
@@ -3082,10 +3136,12 @@
             app.killedByAm = false;
             synchronized (mPidsSelfLocked) {
                 this.mPidsSelfLocked.put(startResult.pid, app);
-                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
-                msg.obj = app;
-                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
-                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
+                if (isActivityProcess) {
+                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
+                    msg.obj = app;
+                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
+                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
+                }
             }
         } catch (RuntimeException e) {
             // XXX do better error recovery.
@@ -3639,7 +3695,7 @@
     }
 
     //explicitly remove thd old information in mRecentTasks when removing existing user.
-    private void removeRecentTasksForUser(int userId) {
+    private void removeRecentTasksForUserLocked(int userId) {
         if(userId <= 0) {
             Slog.i(TAG, "Can't remove recent task on user " + userId);
             return;
@@ -5355,7 +5411,7 @@
             app.deathRecipient = adr;
         } catch (RemoteException e) {
             app.resetPackageList(mProcessStats);
-            startProcessLocked(app, "link fail", processName, null /* ABI override */);
+            startProcessLocked(app, "link fail", processName);
             return false;
         }
 
@@ -5448,7 +5504,7 @@
 
             app.resetPackageList(mProcessStats);
             app.unlinkDeathRecipient();
-            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
+            startProcessLocked(app, "bind fail", processName);
             return false;
         }
 
@@ -5603,7 +5659,7 @@
                 for (int ip=0; ip<NP; ip++) {
                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
                             + procs.get(ip));
-                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
+                    startProcessLocked(procs.get(ip), "on-hold", null);
                 }
             }
             
@@ -6269,7 +6325,10 @@
         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
-            return false;
+            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
+                    != PERMISSION_GRANTED) {
+                return false;
+            }
         }
         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
     }
@@ -8951,29 +9010,35 @@
     // =========================================================
 
     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
-            boolean isolated) {
+            boolean isolated, int isolatedUid) {
         String proc = customProcess != null ? customProcess : info.processName;
         BatteryStatsImpl.Uid.Proc ps = null;
         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
         int uid = info.uid;
         if (isolated) {
-            int userId = UserHandle.getUserId(uid);
-            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
-            while (true) {
-                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
-                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
-                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
+            if (isolatedUid == 0) {
+                int userId = UserHandle.getUserId(uid);
+                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
+                while (true) {
+                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
+                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
+                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
+                    }
+                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
+                    mNextIsolatedProcessUid++;
+                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
+                        // No process for this uid, use it.
+                        break;
+                    }
+                    stepsLeft--;
+                    if (stepsLeft <= 0) {
+                        return null;
+                    }
                 }
-                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
-                mNextIsolatedProcessUid++;
-                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
-                    // No process for this uid, use it.
-                    break;
-                }
-                stepsLeft--;
-                if (stepsLeft <= 0) {
-                    return null;
-                }
+            } else {
+                // Special case for startIsolatedProcess (internal only), where
+                // the uid of the isolated process is specified by the caller.
+                uid = isolatedUid;
             }
         }
         return new ProcessRecord(stats, info, proc, uid);
@@ -8989,7 +9054,7 @@
         }
 
         if (app == null) {
-            app = newProcessRecordLocked(info, null, isolated);
+            app = newProcessRecordLocked(info, null, isolated, 0);
             mProcessNames.put(info.processName, app.uid, app);
             if (isolated) {
                 mIsolatedProcesses.put(app.uid, app);
@@ -9015,8 +9080,8 @@
         }
         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
             mPersistentStartingProcesses.add(app);
-            startProcessLocked(app, "added application", app.processName,
-                    abiOverride);
+            startProcessLocked(app, "added application", app.processName, abiOverride,
+                    null /* entryPoint */, null /* entryPointArgs */);
         }
 
         return app;
@@ -10515,6 +10580,7 @@
             mProcessCrashTimes.put(app.info.processName, app.uid, now);
         }
 
+        if (app.crashHandler != null) mHandler.post(app.crashHandler);
         return true;
     }
 
@@ -13513,7 +13579,7 @@
             // We have components that still need to be running in the
             // process, so re-launch it.
             mProcessNames.put(app.processName, app.uid, app);
-            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
+            startProcessLocked(app, "restart", app.processName);
         } else if (app.pid > 0 && app.pid != MY_PID) {
             // Goodbye!
             boolean removed;
@@ -13765,6 +13831,10 @@
             }
         } else if ("system".equals(componentProcessName)) {
             result = true;
+        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
+                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
+            // Phone app is allowed to export singleuser providers.
+            result = true;
         } else {
             // App with pre-defined UID, check if it's a persistent app
             result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
@@ -17174,6 +17244,10 @@
                     Slog.w(TAG, "No user info for user #" + userId);
                     return false;
                 }
+                if (foreground && userInfo.isManagedProfile()) {
+                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
+                    return false;
+                }
 
                 if (foreground) {
                     mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
@@ -17661,10 +17735,10 @@
                 // Kill all the processes for the user.
                 forceStopUserLocked(userId, "finish user");
             }
-        }
 
-        // Explicitly remove the old information in mRecentTasks.
-        removeRecentTasksForUser(userId);
+            // Explicitly remove the old information in mRecentTasks.
+            removeRecentTasksForUserLocked(userId);
+        }
 
         for (int i=0; i<callbacks.size(); i++) {
             try {
@@ -17845,6 +17919,13 @@
         public void wakingUp() {
             ActivityManagerService.this.wakingUp();
         }
+
+        @Override
+        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
+                String processName, String abiOverride, int uid, Runnable crashHandler) {
+            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
+                    processName, abiOverride, uid, crashHandler);
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 52ace54..b4e66c1 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -97,6 +97,7 @@
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.os.TransferPipe;
 import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.widget.LockPatternUtils;
 import com.android.server.LocalServices;
 import com.android.server.am.ActivityStack.ActivityState;
 import com.android.server.wm.WindowManagerService;
@@ -3327,6 +3328,8 @@
                             if (!mLockTaskIsLocked && shouldLockKeyguard) {
                                 mWindowManager.lockNow(null);
                                 mWindowManager.dismissKeyguard();
+                                new LockPatternUtils(mService.mContext)
+                                        .requireCredentialEntry(UserHandle.USER_ALL);
                             }
                         } catch (SettingNotFoundException e) {
                             // No setting, don't lock.
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index b33f7b7..f1bcb60 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -127,7 +127,8 @@
     Object adjSource;           // Debugging: option dependent object.
     int adjSourceProcState;     // Debugging: proc state of adjSource's process.
     Object adjTarget;           // Debugging: target component impacting oom_adj.
-    
+    Runnable crashHandler;      // Optional local handler to be invoked in the process crash.
+
     // contains HistoryRecord objects
     final ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
     // all ServiceRecord running in this process
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 403713d..4eb2ef1 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -46,6 +46,7 @@
     public int currentScore;
     public final NetworkMonitor networkMonitor;
     public final NetworkMisc networkMisc;
+    public boolean created;
 
     // The list of NetworkRequests being satisfied by this Network.
     public final SparseArray<NetworkRequest> networkRequests = new SparseArray<NetworkRequest>();
@@ -66,6 +67,7 @@
         currentScore = score;
         networkMonitor = new NetworkMonitor(context, handler, this);
         networkMisc = misc;
+        created = false;
     }
 
     public void addRequest(NetworkRequest networkRequest) {
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index 488c09d..ae5eda3 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -26,11 +26,24 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
 import android.os.Handler;
 import android.os.Message;
+import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.telephony.CellIdentityCdma;
+import android.telephony.CellIdentityGsm;
+import android.telephony.CellIdentityLte;
+import android.telephony.CellIdentityWcdma;
+import android.telephony.CellInfo;
+import android.telephony.CellInfoCdma;
+import android.telephony.CellInfoGsm;
+import android.telephony.CellInfoLte;
+import android.telephony.CellInfoWcdma;
+import android.telephony.TelephonyManager;
 
 import com.android.internal.util.Protocol;
 import com.android.internal.util.State;
@@ -38,15 +51,10 @@
 import com.android.server.ConnectivityService;
 import com.android.server.connectivity.NetworkAgentInfo;
 
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
 import java.io.IOException;
-import java.io.OutputStreamWriter;
 import java.net.HttpURLConnection;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
 import java.net.URL;
+import java.util.List;
 
 /**
  * {@hide}
@@ -56,6 +64,21 @@
     private static final String TAG = "NetworkMonitor";
     private static final String DEFAULT_SERVER = "clients3.google.com";
     private static final int SOCKET_TIMEOUT_MS = 10000;
+    public static final String ACTION_NETWORK_CONDITIONS_MEASURED =
+            "android.net.conn.NETWORK_CONDITIONS_MEASURED";
+    public static final String EXTRA_CONNECTIVITY_TYPE = "extra_connectivity_type";
+    public static final String EXTRA_NETWORK_TYPE = "extra_network_type";
+    public static final String EXTRA_RESPONSE_RECEIVED = "extra_response_received";
+    public static final String EXTRA_IS_CAPTIVE_PORTAL = "extra_is_captive_portal";
+    public static final String EXTRA_CELL_ID = "extra_cellid";
+    public static final String EXTRA_SSID = "extra_ssid";
+    public static final String EXTRA_BSSID = "extra_bssid";
+    /** real time since boot */
+    public static final String EXTRA_REQUEST_TIMESTAMP_MS = "extra_request_timestamp_ms";
+    public static final String EXTRA_RESPONSE_TIMESTAMP_MS = "extra_response_timestamp_ms";
+
+    private static final String PERMISSION_ACCESS_NETWORK_CONDITIONS =
+            "android.permission.ACCESS_NETWORK_CONDITIONS";
 
     // Intent broadcast when user selects sign-in notification.
     private static final String ACTION_SIGN_IN_REQUESTED =
@@ -188,6 +211,8 @@
     private final Context mContext;
     private final Handler mConnectivityServiceHandler;
     private final NetworkAgentInfo mNetworkAgentInfo;
+    private final TelephonyManager mTelephonyManager;
+    private final WifiManager mWifiManager;
 
     private String mServer;
     private boolean mIsCaptivePortalCheckEnabled = false;
@@ -209,6 +234,8 @@
         mContext = context;
         mConnectivityServiceHandler = handler;
         mNetworkAgentInfo = networkAgentInfo;
+        mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
 
         addState(mDefaultState);
         addState(mOfflineState, mDefaultState);
@@ -608,84 +635,52 @@
     private int isCaptivePortal() {
         if (!mIsCaptivePortalCheckEnabled) return 204;
 
-        String urlString = "http://" + mServer + "/generate_204";
-        if (DBG) {
-            log("Checking " + urlString + " on " + mNetworkAgentInfo.networkInfo.getExtraInfo());
-        }
         HttpURLConnection urlConnection = null;
-        Socket socket = null;
         int httpResponseCode = 599;
         try {
-            URL url = new URL(urlString);
-            // TODO: check that standard HttpURLConnection doesn't choke on
-            // cruel and unusual captive portals, and then replace the
-            // hand-rolled HTTP code in the else branch with this code.
-            if (false) {
-                url = mNetworkAgentInfo.network.getBoundURL(url);
-                urlConnection = (HttpURLConnection) url.openConnection();
-                urlConnection.setInstanceFollowRedirects(false);
-                urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
-                urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
-                urlConnection.setUseCaches(false);
-                urlConnection.getInputStream();
-                httpResponseCode = urlConnection.getResponseCode();
-            } else {
-                // Lookup addresses only on this Network.
-                InetAddress[] hostAddresses = mNetworkAgentInfo.network.getAllByName(url.getHost());
-                // Try all addresses.
-                for (int i = 0; i < hostAddresses.length; i++) {
-                    // Create a new socket for every IP address. See http://b/16664129 .
-                    socket = mNetworkAgentInfo.network.getSocketFactory().createSocket();
-                    socket.setSoTimeout(SOCKET_TIMEOUT_MS);
-                    if (DBG) log("Connecting to " + hostAddresses[i]);
-                    try {
-                        socket.connect(new InetSocketAddress(hostAddresses[i],
-                                url.getDefaultPort()), SOCKET_TIMEOUT_MS);
-                        break;
-                    } catch (IOException e) {
-                        // Ignore exceptions on all but the last.
-                        if (i == (hostAddresses.length - 1)) throw e;
-                    }
-                }
-                if (DBG) log("Requesting " + url.getFile());
-                BufferedReader reader = new BufferedReader(
-                        new InputStreamReader(socket.getInputStream()));
-                OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream());
-                writer.write("GET " + url.getFile() + " HTTP/1.1\r\nHost: " + url.getHost() +
-                        "\r\nUser-Agent: " + System.getProperty("http.agent") +
-                        "\r\nConnection: close\r\n\r\n");
-                writer.flush();
-                String response = reader.readLine();
-                if (DBG) log("Received \"" + response + "\"");
-                if (response != null && (response.startsWith("HTTP/1.1 ") ||
-                        // NOTE: We may want to consider an "HTTP/1.0 204" response to be a captive
-                        // portal.  The only example of this seen so far was a captive portal.  For
-                        // the time being go with prior behavior of assuming it's not a captive
-                        // portal.  If it is considered a captive portal, a different sign-in URL
-                        // is needed (i.e. can't browse a 204).  This could be the result of an HTTP
-                        // proxy server.
-                        response.startsWith("HTTP/1.0 "))) {
-                    // NOTE: We may want to consider an "200" response with "Content-length=0" to
-                    // not be a captive portal. This could be the result of an HTTP proxy server.
-                    // See b/9972012.
-                    httpResponseCode = Integer.parseInt(response.substring(9, 12));
-                } else {
-                    // A response was received but not understood.  The fact that a
-                    // response was sent indicates there's some kind of responsive network
-                    // out there so put up the notification to the user to log into the network
-                    // so the user can have the final say as to whether the network is useful.
-                    httpResponseCode = 399;
-                    while (DBG && response != null && !response.isEmpty()) {
-                        try {
-                            response = reader.readLine();
-                        } catch (IOException e) {
-                            break;
-                        }
-                        log("Received \"" + response + "\"");
-                    }
-                }
+            URL url = new URL("http", mServer, "/generate_204");
+            if (DBG) {
+                log("Checking " + url.toString() + " on " +
+                        mNetworkAgentInfo.networkInfo.getExtraInfo());
             }
-            if (DBG) log("isCaptivePortal: ret=" + httpResponseCode);
+            url = mNetworkAgentInfo.network.getBoundURL(url);
+            urlConnection = (HttpURLConnection) url.openConnection();
+            urlConnection.setInstanceFollowRedirects(false);
+            urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
+            urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
+            urlConnection.setUseCaches(false);
+
+            // Time how long it takes to get a response to our request
+            long requestTimestamp = SystemClock.elapsedRealtime();
+
+            urlConnection.getInputStream();
+
+            // Time how long it takes to get a response to our request
+            long responseTimestamp = SystemClock.elapsedRealtime();
+
+            httpResponseCode = urlConnection.getResponseCode();
+            if (DBG) {
+                log("isCaptivePortal: ret=" + httpResponseCode +
+                        " headers=" + urlConnection.getHeaderFields());
+            }
+            // NOTE: We may want to consider an "HTTP/1.0 204" response to be a captive
+            // portal.  The only example of this seen so far was a captive portal.  For
+            // the time being go with prior behavior of assuming it's not a captive
+            // portal.  If it is considered a captive portal, a different sign-in URL
+            // is needed (i.e. can't browse a 204).  This could be the result of an HTTP
+            // proxy server.
+
+            // Consider 200 response with "Content-length=0" to not be a captive portal.
+            // There's no point in considering this a captive portal as the user cannot
+            // sign-in to an empty page.  Probably the result of a broken transparent proxy.
+            // See http://b/9972012.
+            if (httpResponseCode == 200 && urlConnection.getContentLength() == 0) {
+                if (DBG) log("Empty 200 response interpreted as 204 response.");
+                httpResponseCode = 204;
+            }
+
+            sendNetworkConditionsBroadcast(true /* response received */, httpResponseCode == 204,
+                    requestTimestamp, responseTimestamp);
         } catch (IOException e) {
             if (DBG) log("Probably not a portal: exception " + e);
             if (httpResponseCode == 599) {
@@ -695,14 +690,87 @@
             if (urlConnection != null) {
                 urlConnection.disconnect();
             }
-            if (socket != null) {
-                try {
-                    socket.close();
-                } catch (IOException e) {
-                    // Ignore
-                }
-            }
         }
         return httpResponseCode;
     }
+
+    /**
+     * @param responseReceived - whether or not we received a valid HTTP response to our request.
+     * If false, isCaptivePortal and responseTimestampMs are ignored
+     * TODO: This should be moved to the transports.  The latency could be passed to the transports
+     * along with the captive portal result.  Currently the TYPE_MOBILE broadcasts appear unused so
+     * perhaps this could just be added to the WiFi transport only.
+     */
+    private void sendNetworkConditionsBroadcast(boolean responseReceived, boolean isCaptivePortal,
+            long requestTimestampMs, long responseTimestampMs) {
+        if (Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 0) {
+            if (DBG) log("Don't send network conditions - lacking user consent.");
+            return;
+        }
+
+        Intent latencyBroadcast = new Intent(ACTION_NETWORK_CONDITIONS_MEASURED);
+        switch (mNetworkAgentInfo.networkInfo.getType()) {
+            case ConnectivityManager.TYPE_WIFI:
+                WifiInfo currentWifiInfo = mWifiManager.getConnectionInfo();
+                if (currentWifiInfo != null) {
+                    // NOTE: getSSID()'s behavior changed in API 17; before that, SSIDs were not
+                    // surrounded by double quotation marks (thus violating the Javadoc), but this
+                    // was changed to match the Javadoc in API 17. Since clients may have started
+                    // sanitizing the output of this method since API 17 was released, we should
+                    // not change it here as it would become impossible to tell whether the SSID is
+                    // simply being surrounded by quotes due to the API, or whether those quotes
+                    // are actually part of the SSID.
+                    latencyBroadcast.putExtra(EXTRA_SSID, currentWifiInfo.getSSID());
+                    latencyBroadcast.putExtra(EXTRA_BSSID, currentWifiInfo.getBSSID());
+                } else {
+                    if (DBG) logw("network info is TYPE_WIFI but no ConnectionInfo found");
+                    return;
+                }
+                break;
+            case ConnectivityManager.TYPE_MOBILE:
+                latencyBroadcast.putExtra(EXTRA_NETWORK_TYPE, mTelephonyManager.getNetworkType());
+                List<CellInfo> info = mTelephonyManager.getAllCellInfo();
+                if (info == null) return;
+                int numRegisteredCellInfo = 0;
+                for (CellInfo cellInfo : info) {
+                    if (cellInfo.isRegistered()) {
+                        numRegisteredCellInfo++;
+                        if (numRegisteredCellInfo > 1) {
+                            if (DBG) log("more than one registered CellInfo.  Can't " +
+                                    "tell which is active.  Bailing.");
+                            return;
+                        }
+                        if (cellInfo instanceof CellInfoCdma) {
+                            CellIdentityCdma cellId = ((CellInfoCdma) cellInfo).getCellIdentity();
+                            latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId);
+                        } else if (cellInfo instanceof CellInfoGsm) {
+                            CellIdentityGsm cellId = ((CellInfoGsm) cellInfo).getCellIdentity();
+                            latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId);
+                        } else if (cellInfo instanceof CellInfoLte) {
+                            CellIdentityLte cellId = ((CellInfoLte) cellInfo).getCellIdentity();
+                            latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId);
+                        } else if (cellInfo instanceof CellInfoWcdma) {
+                            CellIdentityWcdma cellId = ((CellInfoWcdma) cellInfo).getCellIdentity();
+                            latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId);
+                        } else {
+                            if (DBG) logw("Registered cellinfo is unrecognized");
+                            return;
+                        }
+                    }
+                }
+                break;
+            default:
+                return;
+        }
+        latencyBroadcast.putExtra(EXTRA_CONNECTIVITY_TYPE, mNetworkAgentInfo.networkInfo.getType());
+        latencyBroadcast.putExtra(EXTRA_RESPONSE_RECEIVED, responseReceived);
+        latencyBroadcast.putExtra(EXTRA_REQUEST_TIMESTAMP_MS, requestTimestampMs);
+
+        if (responseReceived) {
+            latencyBroadcast.putExtra(EXTRA_IS_CAPTIVE_PORTAL, isCaptivePortal);
+            latencyBroadcast.putExtra(EXTRA_RESPONSE_TIMESTAMP_MS, responseTimestampMs);
+        }
+        mContext.sendBroadcast(latencyBroadcast, PERMISSION_ACCESS_NETWORK_CONDITIONS);
+    }
 }
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index a5f9822..16554d3 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -113,6 +113,12 @@
     }
 
     /**
+     * Sets the refresh rate, if supported.
+     */
+    public void requestRefreshRateLocked(float refreshRate) {
+    }
+
+    /**
      * Sets the display layer stack while in a transaction.
      */
     public final void setLayerStackInTransactionLocked(int layerStack) {
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index c7f4f6a..f48428a 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -21,6 +21,9 @@
 import android.view.Display;
 import android.view.Surface;
 
+import java.util.Arrays;
+
+import libcore.util.EmptyArray;
 import libcore.util.Objects;
 
 /**
@@ -124,6 +127,11 @@
     public float refreshRate;
 
     /**
+     * The supported refresh rates of the display at the current resolution in frames per second.
+     */
+    public float[] supportedRefreshRates = EmptyArray.FLOAT;
+
+    /**
      * The nominal apparent density of the display in DPI used for layout calculations.
      * This density is sensitive to the viewing distance.  A big TV and a tablet may have
      * the same apparent density even though the pixels on the TV are much bigger than
@@ -230,6 +238,7 @@
                 && width == other.width
                 && height == other.height
                 && refreshRate == other.refreshRate
+                && Arrays.equals(supportedRefreshRates, other.supportedRefreshRates)
                 && densityDpi == other.densityDpi
                 && xDpi == other.xDpi
                 && yDpi == other.yDpi
@@ -255,6 +264,7 @@
         width = other.width;
         height = other.height;
         refreshRate = other.refreshRate;
+        supportedRefreshRates = other.supportedRefreshRates;
         densityDpi = other.densityDpi;
         xDpi = other.xDpi;
         yDpi = other.yDpi;
@@ -276,8 +286,9 @@
         StringBuilder sb = new StringBuilder();
         sb.append("DisplayDeviceInfo{\"");
         sb.append(name).append("\": ").append(width).append(" x ").append(height);
-        sb.append(", ").append(refreshRate).append(" fps, ");
-        sb.append("density ").append(densityDpi);
+        sb.append(", ").append(refreshRate).append(" fps");
+        sb.append(", supportedRefreshRates ").append(Arrays.toString(supportedRefreshRates));
+        sb.append(", density ").append(densityDpi);
         sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
         sb.append(", appVsyncOff ").append(appVsyncOffsetNanos);
         sb.append(", presDeadline ").append(presentationDeadlineNanos);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index b9acea5..2dd150a 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -523,6 +523,17 @@
         return -1;
     }
 
+    private void resizeVirtualDisplayInternal(IBinder appToken,
+            int width, int height, int densityDpi) {
+        synchronized (mSyncRoot) {
+            if (mVirtualDisplayAdapter == null) {
+                return;
+            }
+
+            mVirtualDisplayAdapter.resizeVirtualDisplayLocked(appToken, width, height, densityDpi);
+        }
+    }
+
     private void setVirtualDisplaySurfaceInternal(IBinder appToken, Surface surface) {
         synchronized (mSyncRoot) {
             if (mVirtualDisplayAdapter == null) {
@@ -766,11 +777,14 @@
         }
     }
 
-    private void setDisplayHasContentInternal(int displayId, boolean hasContent,
-            boolean inTraversal) {
+    private void setDisplayPropertiesInternal(int displayId, boolean hasContent,
+            float requestedRefreshRate, boolean inTraversal) {
         synchronized (mSyncRoot) {
             LogicalDisplay display = mLogicalDisplays.get(displayId);
-            if (display != null && display.hasContentLocked() != hasContent) {
+            if (display == null) {
+                return;
+            }
+            if (display.hasContentLocked() != hasContent) {
                 if (DEBUG) {
                     Slog.d(TAG, "Display " + displayId + " hasContent flag changed: "
                             + "hasContent=" + hasContent + ", inTraversal=" + inTraversal);
@@ -779,6 +793,14 @@
                 display.setHasContentLocked(hasContent);
                 scheduleTraversalLocked(inTraversal);
             }
+            if (display.getRequestedRefreshRateLocked() != requestedRefreshRate) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Display " + displayId + " has requested a new refresh rate: "
+                            + requestedRefreshRate + "fps");
+                }
+                display.setRequestedRefreshRateLocked(requestedRefreshRate);
+                scheduleTraversalLocked(inTraversal);
+            }
         }
     }
 
@@ -1304,6 +1326,17 @@
         }
 
         @Override // Binder call
+        public void resizeVirtualDisplay(IVirtualDisplayCallbacks callbacks,
+                int width, int height, int densityDpi) {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                resizeVirtualDisplayInternal(callbacks.asBinder(), width, height, densityDpi);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override // Binder call
         public void setVirtualDisplaySurface(IVirtualDisplayCallbacks callbacks, Surface surface) {
             final long token = Binder.clearCallingIdentity();
             try {
@@ -1460,8 +1493,9 @@
         }
 
         @Override
-        public void setDisplayHasContent(int displayId, boolean hasContent, boolean inTraversal) {
-            setDisplayHasContentInternal(displayId, hasContent, inTraversal);
+        public void setDisplayProperties(int displayId, boolean hasContent,
+                float requestedRefreshRate, boolean inTraversal) {
+            setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate, inTraversal);
         }
     }
 }
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 2bed143..4fd006d 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -21,6 +21,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.SystemProperties;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.view.Display;
@@ -29,6 +30,7 @@
 import android.view.SurfaceControl;
 
 import java.io.PrintWriter;
+import java.util.Arrays;
 
 /**
  * A display adapter for the local displays managed by Surface Flinger.
@@ -88,10 +90,10 @@
             if (device == null) {
                 // Display was added.
                 device = new LocalDisplayDevice(displayToken, builtInDisplayId,
-                        configs[activeConfig]);
+                        configs, activeConfig);
                 mDevices.put(builtInDisplayId, device);
                 sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
-            } else if (device.updatePhysicalDisplayInfoLocked(configs[activeConfig])) {
+            } else if (device.updatePhysicalDisplayInfoLocked(configs, activeConfig)) {
                 // Display properties changed.
                 sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_CHANGED);
             }
@@ -127,21 +129,31 @@
     private final class LocalDisplayDevice extends DisplayDevice {
         private final int mBuiltInDisplayId;
         private final SurfaceControl.PhysicalDisplayInfo mPhys;
+        private final int mDefaultPhysicalDisplayInfo;
 
         private DisplayDeviceInfo mInfo;
         private boolean mHavePendingChanges;
         private int mState = Display.STATE_UNKNOWN;
+        private float[] mSupportedRefreshRates;
+        private int[] mRefreshRateConfigIndices;
+        private float mLastRequestedRefreshRate;
 
         public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,
-                SurfaceControl.PhysicalDisplayInfo phys) {
+                SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) {
             super(LocalDisplayAdapter.this, displayToken);
             mBuiltInDisplayId = builtInDisplayId;
-            mPhys = new SurfaceControl.PhysicalDisplayInfo(phys);
+            mPhys = new SurfaceControl.PhysicalDisplayInfo(
+                    physicalDisplayInfos[activeDisplayInfo]);
+            mDefaultPhysicalDisplayInfo = activeDisplayInfo;
+            updateSupportedRefreshRatesLocked(physicalDisplayInfos, mPhys);
         }
 
-        public boolean updatePhysicalDisplayInfoLocked(SurfaceControl.PhysicalDisplayInfo phys) {
-            if (!mPhys.equals(phys)) {
-                mPhys.copyFrom(phys);
+        public boolean updatePhysicalDisplayInfoLocked(
+                SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) {
+            SurfaceControl.PhysicalDisplayInfo newPhys = physicalDisplayInfos[activeDisplayInfo];
+            if (!mPhys.equals(newPhys)) {
+                mPhys.copyFrom(newPhys);
+                updateSupportedRefreshRatesLocked(physicalDisplayInfos, mPhys);
                 mHavePendingChanges = true;
                 return true;
             }
@@ -163,6 +175,7 @@
                 mInfo.width = mPhys.width;
                 mInfo.height = mPhys.height;
                 mInfo.refreshRate = mPhys.refreshRate;
+                mInfo.supportedRefreshRates = mSupportedRefreshRates;
                 mInfo.appVsyncOffsetNanos = mPhys.appVsyncOffsetNanos;
                 mInfo.presentationDeadlineNanos = mPhys.presentationDeadlineNanos;
                 mInfo.state = mState;
@@ -219,6 +232,26 @@
         }
 
         @Override
+        public void requestRefreshRateLocked(float refreshRate) {
+            if (mLastRequestedRefreshRate == refreshRate) {
+                return;
+            }
+            mLastRequestedRefreshRate = refreshRate;
+            if (refreshRate != 0) {
+                final int N = mSupportedRefreshRates.length;
+                for (int i = 0; i < N; i++) {
+                    if (refreshRate == mSupportedRefreshRates[i]) {
+                        final int configIndex = mRefreshRateConfigIndices[i];
+                        SurfaceControl.setActiveConfig(getDisplayTokenLocked(), configIndex);
+                        return;
+                    }
+                }
+                Slog.w(TAG, "Requested refresh rate " + refreshRate + " is unsupported.");
+            }
+            SurfaceControl.setActiveConfig(getDisplayTokenLocked(), mDefaultPhysicalDisplayInfo);
+        }
+
+        @Override
         public void dumpLocked(PrintWriter pw) {
             super.dumpLocked(pw);
             pw.println("mBuiltInDisplayId=" + mBuiltInDisplayId);
@@ -230,6 +263,30 @@
             mInfo = null;
             sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
         }
+
+        private void updateSupportedRefreshRatesLocked(
+                SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos,
+                SurfaceControl.PhysicalDisplayInfo activePhys) {
+            final int N = physicalDisplayInfos.length;
+            int idx = 0;
+            mSupportedRefreshRates = new float[N];
+            mRefreshRateConfigIndices = new int[N];
+            for (int i = 0; i < N; i++) {
+                final SurfaceControl.PhysicalDisplayInfo phys = physicalDisplayInfos[i];
+                if (activePhys.width == phys.width
+                        && activePhys.height == phys.height
+                        && activePhys.density == phys.density
+                        && activePhys.xDpi == phys.xDpi
+                        && activePhys.yDpi == phys.yDpi) {
+                    mSupportedRefreshRates[idx] = phys.refreshRate;
+                    mRefreshRateConfigIndices[idx++] = i;
+                }
+            }
+            if (idx != N) {
+                mSupportedRefreshRates = Arrays.copyOfRange(mSupportedRefreshRates, 0, idx);
+                mRefreshRateConfigIndices = Arrays.copyOfRange(mRefreshRateConfigIndices, 0, idx);
+            }
+        }
     }
 
     private final class HotplugDisplayEventReceiver extends DisplayEventReceiver {
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 284780d..00ff1cf 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -22,6 +22,7 @@
 import android.view.Surface;
 
 import java.io.PrintWriter;
+import java.util.Arrays;
 import java.util.List;
 
 import libcore.util.Objects;
@@ -72,6 +73,9 @@
     // True if the logical display has unique content.
     private boolean mHasContent;
 
+    // The pending requested refresh rate. 0 if no request is pending.
+    private float mRequestedRefreshRate;
+
     // Temporary rectangle used when needed.
     private final Rect mTempLayerStackRect = new Rect();
     private final Rect mTempDisplayRect = new Rect();
@@ -210,6 +214,8 @@
             mBaseDisplayInfo.logicalHeight = deviceInfo.height;
             mBaseDisplayInfo.rotation = Surface.ROTATION_0;
             mBaseDisplayInfo.refreshRate = deviceInfo.refreshRate;
+            mBaseDisplayInfo.supportedRefreshRates = Arrays.copyOf(
+                    deviceInfo.supportedRefreshRates, deviceInfo.supportedRefreshRates.length);
             mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi;
             mBaseDisplayInfo.physicalXDpi = deviceInfo.xDpi;
             mBaseDisplayInfo.physicalYDpi = deviceInfo.yDpi;
@@ -253,6 +259,9 @@
         // Set the layer stack.
         device.setLayerStackInTransactionLocked(isBlanked ? BLANK_LAYER_STACK : mLayerStack);
 
+        // Set the refresh rate
+        device.requestRefreshRateLocked(mRequestedRefreshRate);
+
         // Set the viewport.
         // This is the area of the logical display that we intend to show on the
         // display device.  For now, it is always the full size of the logical display.
@@ -328,6 +337,23 @@
         mHasContent = hasContent;
     }
 
+    /**
+     * Requests the given refresh rate.
+     * @param requestedRefreshRate The desired refresh rate.
+     */
+    public void setRequestedRefreshRateLocked(float requestedRefreshRate) {
+        mRequestedRefreshRate = requestedRefreshRate;
+    }
+
+    /**
+     * Gets the pending requested refresh rate.
+     *
+     * @return The pending refresh rate requested
+     */
+    public float getRequestedRefreshRateLocked() {
+        return mRequestedRefreshRate;
+    }
+
     public void dumpLocked(PrintWriter pw) {
         pw.println("mDisplayId=" + mDisplayId);
         pw.println("mLayerStack=" + mLayerStack);
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 1032081..0ebd2de 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -83,6 +83,15 @@
         return device;
     }
 
+    public void resizeVirtualDisplayLocked(IBinder appToken,
+            int width, int height, int densityDpi) {
+        VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
+        if (device != null) {
+            device.resizeLocked(width, height, densityDpi);
+        }
+    }
+
+
     public void setVirtualDisplaySurfaceLocked(IBinder appToken, Surface surface) {
         VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
         if (device != null) {
@@ -122,20 +131,24 @@
     }
 
     private final class VirtualDisplayDevice extends DisplayDevice implements DeathRecipient {
+        private static final int PENDING_SURFACE_CHANGE = 0x01;
+        private static final int PENDING_RESIZE = 0x02;
+
         private final IBinder mAppToken;
         private final int mOwnerUid;
         final String mOwnerPackageName;
         final String mName;
-        private final int mWidth;
-        private final int mHeight;
-        private final int mDensityDpi;
         private final int mFlags;
         private final Callbacks mCallbacks;
 
+        private int mWidth;
+        private int mHeight;
+        private int mDensityDpi;
         private Surface mSurface;
         private DisplayDeviceInfo mInfo;
-        private int mState;
+        private int mDisplayState;
         private boolean mStopped;
+        private int mPendingChanges;
 
         public VirtualDisplayDevice(IBinder displayToken, IBinder appToken,
                 int ownerUid, String ownerPackageName,
@@ -152,7 +165,8 @@
             mSurface = surface;
             mFlags = flags;
             mCallbacks = callbacks;
-            mState = Display.STATE_UNKNOWN;
+            mDisplayState = Display.STATE_UNKNOWN;
+            mPendingChanges |= PENDING_SURFACE_CHANGE;
         }
 
         @Override
@@ -175,8 +189,8 @@
 
         @Override
         public void requestDisplayStateLocked(int state) {
-            if (state != mState) {
-                mState = state;
+            if (state != mDisplayState) {
+                mDisplayState = state;
                 if (state == Display.STATE_OFF) {
                     mCallbacks.dispatchDisplayPaused();
                 } else {
@@ -187,7 +201,13 @@
 
         @Override
         public void performTraversalInTransactionLocked() {
-            setSurfaceInTransactionLocked(mSurface);
+            if ((mPendingChanges & PENDING_RESIZE) != 0) {
+                SurfaceControl.setDisplaySize(getDisplayTokenLocked(), mWidth, mHeight);
+            }
+            if ((mPendingChanges & PENDING_SURFACE_CHANGE) != 0) {
+                setSurfaceInTransactionLocked(mSurface);
+            }
+            mPendingChanges = 0;
         }
 
         public void setSurfaceLocked(Surface surface) {
@@ -198,6 +218,19 @@
                 sendTraversalRequestLocked();
                 mSurface = surface;
                 mInfo = null;
+                mPendingChanges |= PENDING_SURFACE_CHANGE;
+            }
+        }
+
+        public void resizeLocked(int width, int height, int densityDpi) {
+            if (mWidth != width || mHeight != height || mDensityDpi != densityDpi) {
+                sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
+                sendTraversalRequestLocked();
+                mWidth = width;
+                mHeight = height;
+                mDensityDpi = densityDpi;
+                mInfo = null;
+                mPendingChanges |= PENDING_RESIZE;
             }
         }
 
@@ -210,7 +243,7 @@
         public void dumpLocked(PrintWriter pw) {
             super.dumpLocked(pw);
             pw.println("mFlags=" + mFlags);
-            pw.println("mState=" + Display.stateToString(mState));
+            pw.println("mDisplayState=" + Display.stateToString(mDisplayState));
             pw.println("mStopped=" + mStopped);
         }
 
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index b894304..985f77a 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -249,7 +249,7 @@
 
     private ComponentName chooseDreamForUser(boolean doze, int userId) {
         if (doze) {
-            ComponentName dozeComponent = getDozeComponent();
+            ComponentName dozeComponent = getDozeComponent(userId);
             return validateDream(dozeComponent) ? dozeComponent : null;
         }
         ComponentName[] dreams = getDreamComponentsForUser(userId);
@@ -314,6 +314,10 @@
     }
 
     private ComponentName getDozeComponent() {
+        return getDozeComponent(ActivityManager.getCurrentUser());
+    }
+
+    private ComponentName getDozeComponent(int userId) {
         // Read the component from a system property to facilitate debugging.
         // Note that for production devices, the dream should actually be declared in
         // a config.xml resource.
@@ -324,7 +328,9 @@
             name = mContext.getResources().getString(
                     com.android.internal.R.string.config_dozeComponent);
         }
-        return TextUtils.isEmpty(name) ? null : ComponentName.unflattenFromString(name);
+        boolean enabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.DOZE_ENABLED, 1, userId) != 0;
+        return TextUtils.isEmpty(name) || !enabled ? null : ComponentName.unflattenFromString(name);
     }
 
     private ServiceInfo getServiceInfo(ComponentName name) {
diff --git a/services/core/java/com/android/server/hdmi/ActiveSourceHandler.java b/services/core/java/com/android/server/hdmi/ActiveSourceHandler.java
index 0b9094f..cb92112 100644
--- a/services/core/java/com/android/server/hdmi/ActiveSourceHandler.java
+++ b/services/core/java/com/android/server/hdmi/ActiveSourceHandler.java
@@ -18,7 +18,7 @@
 
 import android.annotation.Nullable;
 import android.hardware.hdmi.IHdmiControlCallback;
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.HdmiControlManager;
 import android.os.RemoteException;
 import android.util.Slog;
@@ -66,7 +66,7 @@
             invokeCallback(HdmiControlManager.RESULT_SUCCESS);
             return;
         }
-        HdmiCecDeviceInfo device = mService.getDeviceInfo(newActive.logicalAddress);
+        HdmiDeviceInfo device = mService.getDeviceInfo(newActive.logicalAddress);
         if (device == null) {
             tv.startNewDeviceAction(newActive);
         }
@@ -101,10 +101,6 @@
         return mSource.getDeviceInfo().getLogicalAddress();
     }
 
-    private final int getSourcePath() {
-        return mSource.getDeviceInfo().getPhysicalAddress();
-    }
-
     private void invokeCallback(int result) {
         if (mCallback == null) {
             return;
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index bfbaefe..0b57474 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -16,12 +16,12 @@
 
 package com.android.server.hdmi;
 
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 
 /**
  * Defines constants related to HDMI-CEC protocol internal implementation.
  * If a constant will be used in the public api, it should be located in
- * {@link android.hardware.hdmi.HdmiCec}.
+ * {@link android.hardware.hdmi.HdmiControlManager}.
  */
 final class Constants {
 
@@ -80,7 +80,7 @@
     public static final int ADDR_INVALID = -1;
 
     /** Logical address used to indicate the source comes from internal device. */
-    public static final int ADDR_INTERNAL = HdmiCecDeviceInfo.ADDR_INTERNAL;
+    public static final int ADDR_INTERNAL = HdmiDeviceInfo.ADDR_INTERNAL;
 
     static final int MESSAGE_FEATURE_ABORT = 0x00;
     static final int MESSAGE_IMAGE_VIEW_ON = 0x04;
@@ -162,7 +162,7 @@
     // Constants related to operands of HDMI CEC commands.
     // Refer to CEC Table 29 in HDMI Spec v1.4b.
     // [Abort Reason]
-    static final int ABORT_UNRECOGNIZED_MODE = 0;
+    static final int ABORT_UNRECOGNIZED_OPCODE = 0;
     static final int ABORT_NOT_IN_CORRECT_MODE = 1;
     static final int ABORT_CANNOT_PROVIDE_SOURCE = 2;
     static final int ABORT_INVALID_OPERAND = 3;
@@ -178,8 +178,8 @@
     static final int ROUTING_PATH_TOP_MASK = 0xF000;
     static final int ROUTING_PATH_TOP_SHIFT = 12;
 
-    static final int INVALID_PORT_ID = HdmiCecDeviceInfo.PORT_INVALID;
-    static final int INVALID_PHYSICAL_ADDRESS = HdmiCecDeviceInfo.PATH_INVALID;
+    static final int INVALID_PORT_ID = HdmiDeviceInfo.PORT_INVALID;
+    static final int INVALID_PHYSICAL_ADDRESS = HdmiDeviceInfo.PATH_INVALID;
 
     // Send result codes. It should be consistent with hdmi_cec.h's send_message error code.
     static final int SEND_RESULT_SUCCESS = 0;
diff --git a/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java b/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java
index 86e14e1..d67b8f1 100644
--- a/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java
+++ b/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java
@@ -16,7 +16,7 @@
 
 package com.android.server.hdmi;
 
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.util.Slog;
 
 import com.android.internal.util.Preconditions;
@@ -39,7 +39,7 @@
  *   <li>Gather "Vendor id" of all acknowledge devices
  * </ol>
  */
-final class DeviceDiscoveryAction extends FeatureAction {
+final class DeviceDiscoveryAction extends HdmiCecFeatureAction {
     private static final String TAG = "DeviceDiscoveryAction";
 
     // State in which the action is waiting for device polling.
@@ -60,7 +60,7 @@
          *
          * @param deviceInfos a list of all non-local devices. It can be empty list.
          */
-        void onDeviceDiscoveryDone(List<HdmiCecDeviceInfo> deviceInfos);
+        void onDeviceDiscoveryDone(List<HdmiDeviceInfo> deviceInfos);
     }
 
     // An internal container used to keep track of device information during
@@ -72,14 +72,14 @@
         private int mPortId = Constants.INVALID_PORT_ID;
         private int mVendorId = Constants.UNKNOWN_VENDOR_ID;
         private String mDisplayName = "";
-        private int mDeviceType = HdmiCecDeviceInfo.DEVICE_INACTIVE;
+        private int mDeviceType = HdmiDeviceInfo.DEVICE_INACTIVE;
 
         private DeviceInfo(int logicalAddress) {
             mLogicalAddress = logicalAddress;
         }
 
-        private HdmiCecDeviceInfo toHdmiCecDeviceInfo() {
-            return new HdmiCecDeviceInfo(mLogicalAddress, mPhysicalAddress, mPortId, mDeviceType,
+        private HdmiDeviceInfo toHdmiDeviceInfo() {
+            return new HdmiDeviceInfo(mLogicalAddress, mPhysicalAddress, mPortId, mDeviceType,
                     mVendorId, mDisplayName);
         }
     }
@@ -314,9 +314,9 @@
 
     private void wrapUpAndFinish() {
         Slog.v(TAG, "---------Wrap up Device Discovery:[" + mDevices.size() + "]---------");
-        ArrayList<HdmiCecDeviceInfo> result = new ArrayList<>();
+        ArrayList<HdmiDeviceInfo> result = new ArrayList<>();
         for (DeviceInfo info : mDevices) {
-            HdmiCecDeviceInfo cecDeviceInfo = info.toHdmiCecDeviceInfo();
+            HdmiDeviceInfo cecDeviceInfo = info.toHdmiDeviceInfo();
             Slog.v(TAG, " DeviceInfo: " + cecDeviceInfo);
             result.add(cecDeviceInfo);
         }
diff --git a/services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java b/services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java
index 1106810..d965caa 100644
--- a/services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java
+++ b/services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java
@@ -17,20 +17,20 @@
  */
 
 import android.hardware.hdmi.HdmiControlManager;
+import android.hardware.hdmi.HdmiPlaybackClient;
+import android.hardware.hdmi.HdmiPlaybackClient.DisplayStatusCallback;
 import android.hardware.hdmi.IHdmiControlCallback;
 import android.os.RemoteException;
 import android.util.Slog;
 
 /**
- * Feature action that queries the power status of other device.
- *
- * This action is initiated via {@link HdmiControlManager#queryDisplayStatus()} from
- * the Android system working as playback device to get the power status of TV device.
- *
- * <p>Package-private, accessed by {@link HdmiControlService} only.
+ * Feature action that queries the power status of other device. This action is initiated via
+ * {@link HdmiPlaybackClient#queryDisplayStatus(DisplayStatusCallback)} from the Android system
+ * working as playback device to get the power status of TV device.
+ * <p>
+ * Package-private, accessed by {@link HdmiControlService} only.
  */
-
-final class DevicePowerStatusAction extends FeatureAction {
+final class DevicePowerStatusAction extends HdmiCecFeatureAction {
     private static final String TAG = "DevicePowerStatusAction";
 
     // State in which the action is waiting for <Report Power Status>.
diff --git a/services/core/java/com/android/server/hdmi/DeviceSelectAction.java b/services/core/java/com/android/server/hdmi/DeviceSelectAction.java
index 018b34d..ed37ead 100644
--- a/services/core/java/com/android/server/hdmi/DeviceSelectAction.java
+++ b/services/core/java/com/android/server/hdmi/DeviceSelectAction.java
@@ -16,7 +16,7 @@
 
 package com.android.server.hdmi;
 
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiTvClient;
 import android.hardware.hdmi.IHdmiControlCallback;
@@ -33,7 +33,7 @@
  * for a new active source. It does its best to wake up the target in standby mode
  * before issuing the command &gt;Set Stream path&lt;.
  */
-final class DeviceSelectAction extends FeatureAction {
+final class DeviceSelectAction extends HdmiCecFeatureAction {
     private static final String TAG = "DeviceSelect";
 
     // Time in milliseconds we wait for the device power status to switch to 'Standby'
@@ -67,7 +67,7 @@
     // before we give up and mark the action as failure.
     private static final int STATE_WAIT_FOR_ACTIVE_SOURCE = 4;
 
-    private final HdmiCecDeviceInfo mTarget;
+    private final HdmiDeviceInfo mTarget;
     private final IHdmiControlCallback mCallback;
     private final HdmiCecMessage mGivePowerStatus;
 
@@ -81,7 +81,7 @@
      * @param callback callback object
      */
     public DeviceSelectAction(HdmiCecLocalDeviceTv source,
-            HdmiCecDeviceInfo target, IHdmiControlCallback callback) {
+            HdmiDeviceInfo target, IHdmiControlCallback callback) {
         super(source);
         mCallback = callback;
         mTarget = target;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index cbccc1d..10e4b6e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -65,16 +65,6 @@
 
     private static final byte[] EMPTY_BODY = EmptyArray.BYTE;
 
-    // A message to pass cec send command to IO looper.
-    private static final int MSG_SEND_CEC_COMMAND = 1;
-    // A message to delegate logical allocation to IO looper.
-    private static final int MSG_ALLOCATE_LOGICAL_ADDRESS = 2;
-
-    // Message types to handle incoming message in main service looper.
-    private final static int MSG_RECEIVE_CEC_COMMAND = 1;
-    // A message to report allocated logical address to main control looper.
-    private final static int MSG_REPORT_LOGICAL_ADDRESS = 2;
-
     private static final int NUM_LOGICAL_ADDRESS = 16;
 
     // Predicate for whether the given logical address is remote device's one or not.
@@ -196,7 +186,15 @@
             int curAddress = (startAddress + i) % NUM_LOGICAL_ADDRESS;
             if (curAddress != Constants.ADDR_UNREGISTERED
                     && deviceType == HdmiUtils.getTypeFromAddress(curAddress)) {
-                if (!sendPollMessage(curAddress, curAddress, HdmiConfig.ADDRESS_ALLOCATION_RETRY)) {
+                int failedPollingCount = 0;
+                for (int j = 0; j < HdmiConfig.ADDRESS_ALLOCATION_RETRY; ++j) {
+                    if (!sendPollMessage(curAddress, curAddress, 1)) {
+                        failedPollingCount++;
+                    }
+                }
+
+                // Pick logical address if failed ratio is more than a half of all retries.
+                if (failedPollingCount * 2 >  HdmiConfig.ADDRESS_ALLOCATION_RETRY) {
                     logicalAddress = curAddress;
                     break;
                 }
@@ -206,7 +204,7 @@
         final int assignedAddress = logicalAddress;
         if (callback != null) {
             runOnServiceThread(new Runnable() {
-                    @Override
+                @Override
                 public void run() {
                     callback.onAllocated(deviceType, assignedAddress);
                 }
@@ -502,24 +500,30 @@
     @ServiceThreadOnly
     private void onReceiveCommand(HdmiCecMessage message) {
         assertRunOnServiceThread();
-        if (isAcceptableAddress(message.getDestination())
-                && mService.handleCecCommand(message)) {
+        if (isAcceptableAddress(message.getDestination()) && mService.handleCecCommand(message)) {
             return;
         }
-        if (message.getDestination() == Constants.ADDR_BROADCAST) {
-            return;
-        }
-        if (message.getOpcode() == Constants.MESSAGE_FEATURE_ABORT) {
-            Slog.v(TAG, "Unhandled <Feature Abort> message:" + message);
-            return;
-        }
+        // Not handled message, so we will reply it with <Feature Abort>.
+        maySendFeatureAbortCommand(message, Constants.ABORT_UNRECOGNIZED_OPCODE);
+    }
 
-        int sourceAddress = message.getDestination();
-        // Reply <Feature Abort> to initiator (source) for all requests.
-        HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildFeatureAbortCommand(
-                sourceAddress, message.getSource(), message.getOpcode(),
-                Constants.ABORT_REFUSED);
-        sendCommand(cecMessage);
+    @ServiceThreadOnly
+    void maySendFeatureAbortCommand(HdmiCecMessage message, int reason) {
+        assertRunOnServiceThread();
+        // Swap the source and the destination.
+        int src = message.getDestination();
+        int dest = message.getSource();
+        if (src == Constants.ADDR_BROADCAST || dest == Constants.ADDR_UNREGISTERED) {
+            // Don't reply <Feature Abort> from the unregistered devices or for the broadcasted
+            // messages. See CEC 12.2 Protocol General Rules for detail.
+            return;
+        }
+        int originalOpcode = message.getOpcode();
+        if (originalOpcode == Constants.MESSAGE_FEATURE_ABORT) {
+            return;
+        }
+        sendCommand(
+                HdmiCecMessageBuilder.buildFeatureAbortCommand(src, dest, originalOpcode, reason));
     }
 
     @ServiceThreadOnly
diff --git a/services/core/java/com/android/server/hdmi/FeatureAction.java b/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
similarity index 82%
rename from services/core/java/com/android/server/hdmi/FeatureAction.java
rename to services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
index b7b2f90..f32e660 100644
--- a/services/core/java/com/android/server/hdmi/FeatureAction.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
@@ -29,21 +29,19 @@
 
 /**
  * Encapsulates a sequence of CEC/MHL command exchange for a certain feature.
- *
- * <p>Many CEC/MHL features are accomplished by CEC devices on the bus exchanging
- * more than one command. {@link FeatureAction} represents the life cycle of the communication,
- * manages the state as the process progresses, and if necessary, returns the result
- * to the caller which initiates the action, through the callback given at the creation
- * of the object. All the actual action classes inherit FeatureAction.
- *
- * <p>More than one FeatureAction objects can be up and running simultaneously,
- * maintained by {@link HdmiCecLocalDevice}. Each action is passed a new command
- * arriving from the bus, and either consumes it if the command is what the action expects,
- * or yields it to other action.
- *
- * Declared as package private, accessed by {@link HdmiControlService} only.
+ * <p>
+ * Many CEC/MHL features are accomplished by CEC devices on the bus exchanging more than one
+ * command. {@link HdmiCecFeatureAction} represents the life cycle of the communication, manages the
+ * state as the process progresses, and if necessary, returns the result to the caller which
+ * initiates the action, through the callback given at the creation of the object. All the actual
+ * action classes inherit FeatureAction.
+ * <p>
+ * More than one FeatureAction objects can be up and running simultaneously, maintained by
+ * {@link HdmiCecLocalDevice}. Each action is passed a new command arriving from the bus, and either
+ * consumes it if the command is what the action expects, or yields it to other action. Declared as
+ * package private, accessed by {@link HdmiControlService} only.
  */
-abstract class FeatureAction {
+abstract class HdmiCecFeatureAction {
     private static final String TAG = "FeatureAction";
 
     // Timer handler message used for timeout event
@@ -61,9 +59,9 @@
     // Timer that manages timeout events.
     protected ActionTimer mActionTimer;
 
-    private ArrayList<Pair<FeatureAction, Runnable>> mOnFinishedCallbacks;
+    private ArrayList<Pair<HdmiCecFeatureAction, Runnable>> mOnFinishedCallbacks;
 
-    FeatureAction(HdmiCecLocalDevice source) {
+    HdmiCecFeatureAction(HdmiCecLocalDevice source) {
         mSource = source;
         mService = mSource.getService();
         mActionTimer = createActionTimer(mService.getServiceLooper());
@@ -173,11 +171,11 @@
         mService.sendCecCommand(cmd, callback);
     }
 
-    protected final void addAndStartAction(FeatureAction action) {
+    protected final void addAndStartAction(HdmiCecFeatureAction action) {
         mSource.addAndStartAction(action);
     }
 
-    protected final <T extends FeatureAction> List<T> getActions(final Class<T> clazz) {
+    protected final <T extends HdmiCecFeatureAction> List<T> getActions(final Class<T> clazz) {
         return mSource.getActions(clazz);
     }
 
@@ -191,16 +189,16 @@
      *
      * @param action
      */
-    protected final void removeAction(FeatureAction action) {
+    protected final void removeAction(HdmiCecFeatureAction action) {
         mSource.removeAction(action);
     }
 
-    protected final <T extends FeatureAction> void removeAction(final Class<T> clazz) {
+    protected final <T extends HdmiCecFeatureAction> void removeAction(final Class<T> clazz) {
         mSource.removeActionExcept(clazz, null);
     }
 
-    protected final <T extends FeatureAction> void removeActionExcept(final Class<T> clazz,
-            final FeatureAction exception) {
+    protected final <T extends HdmiCecFeatureAction> void removeActionExcept(final Class<T> clazz,
+            final HdmiCecFeatureAction exception) {
         mSource.removeActionExcept(clazz, exception);
     }
 
@@ -233,7 +231,7 @@
             removeAction(this);
         }
         if (mOnFinishedCallbacks != null) {
-            for (Pair<FeatureAction, Runnable> actionCallbackPair: mOnFinishedCallbacks) {
+            for (Pair<HdmiCecFeatureAction, Runnable> actionCallbackPair: mOnFinishedCallbacks) {
                 if (actionCallbackPair.first.mState != STATE_NONE) {
                     actionCallbackPair.second.run();
                 }
@@ -269,7 +267,7 @@
                 getSourceAddress(), targetAddress));
     }
 
-    protected final void addOnFinishedCallback(FeatureAction action, Runnable runnable) {
+    protected final void addOnFinishedCallback(HdmiCecFeatureAction action, Runnable runnable) {
         if (mOnFinishedCallbacks == null) {
             mOnFinishedCallbacks = new ArrayList<>();
         }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index c16be50..be4c834 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -16,7 +16,7 @@
 
 package com.android.server.hdmi;
 
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -47,7 +47,7 @@
     protected final int mDeviceType;
     protected int mAddress;
     protected int mPreferredAddress;
-    protected HdmiCecDeviceInfo mDeviceInfo;
+    protected HdmiDeviceInfo mDeviceInfo;
 
     static class ActiveSource {
         int logicalAddress;
@@ -102,7 +102,7 @@
 
     // A collection of FeatureAction.
     // Note that access to this collection should happen in service thread.
-    private final LinkedList<FeatureAction> mActions = new LinkedList<>();
+    private final LinkedList<HdmiCecFeatureAction> mActions = new LinkedList<>();
 
     private final Handler mHandler = new Handler () {
         @Override
@@ -135,9 +135,9 @@
     // Factory method that returns HdmiCecLocalDevice of corresponding type.
     static HdmiCecLocalDevice create(HdmiControlService service, int deviceType) {
         switch (deviceType) {
-        case HdmiCecDeviceInfo.DEVICE_TV:
+        case HdmiDeviceInfo.DEVICE_TV:
             return new HdmiCecLocalDeviceTv(service);
-        case HdmiCecDeviceInfo.DEVICE_PLAYBACK:
+        case HdmiDeviceInfo.DEVICE_PLAYBACK:
             return new HdmiCecLocalDevicePlayback(service);
         default:
             return null;
@@ -153,7 +153,7 @@
     /**
      * Called once a logical address of the local device is allocated.
      */
-    protected abstract void onAddressAllocated(int logicalAddress, boolean fromBootup);
+    protected abstract void onAddressAllocated(int logicalAddress, int reason);
 
     /**
      * Get the preferred logical address from system properties.
@@ -172,7 +172,7 @@
      * @return true if consumed a message; otherwise, return false.
      */
     @ServiceThreadOnly
-    final boolean dispatchMessage(HdmiCecMessage message) {
+    boolean dispatchMessage(HdmiCecMessage message) {
         assertRunOnServiceThread();
         int dest = message.getDestination();
         if (dest != mAddress && dest != Constants.ADDR_BROADCAST) {
@@ -240,6 +240,8 @@
                 return handleSetOsdName(message);
             case Constants.MESSAGE_RECORD_TV_SCREEN:
                 return handleRecordTvScreen(message);
+            case Constants.MESSAGE_TIMER_CLEARED_STATUS:
+                return handleTimerClearedStatus(message);
             default:
                 return false;
         }
@@ -248,7 +250,7 @@
     @ServiceThreadOnly
     private boolean dispatchMessageToAction(HdmiCecMessage message) {
         assertRunOnServiceThread();
-        for (FeatureAction action : mActions) {
+        for (HdmiCecFeatureAction action : mActions) {
             if (action.processCommand(message)) {
                 return true;
             }
@@ -306,11 +308,8 @@
     protected boolean handleGetMenuLanguage(HdmiCecMessage message) {
         assertRunOnServiceThread();
         Slog.w(TAG, "Only TV can handle <Get Menu Language>:" + message.toString());
-        mService.sendCecCommand(
-                HdmiCecMessageBuilder.buildFeatureAbortCommand(mAddress,
-                        message.getSource(), Constants.MESSAGE_GET_MENU_LANGUAGE,
-                        Constants.ABORT_UNRECOGNIZED_MODE));
-        return true;
+        // 'return false' will cause to reply with <Feature Abort>.
+        return false;
     }
 
     @ServiceThreadOnly
@@ -381,7 +380,7 @@
         return false;
     }
 
-    private static boolean isPowerOnOrToggleCommand(HdmiCecMessage message) {
+    static boolean isPowerOnOrToggleCommand(HdmiCecMessage message) {
         byte[] params = message.getParams();
         return message.getOpcode() == Constants.MESSAGE_USER_CONTROL_PRESSED
                 && (params[0] == HdmiCecKeycode.CEC_KEYCODE_POWER
@@ -389,7 +388,7 @@
                         || params[0] == HdmiCecKeycode.CEC_KEYCODE_POWER_TOGGLE_FUNCTION);
     }
 
-    private static boolean isPowerOffOrToggleCommand(HdmiCecMessage message) {
+    static boolean isPowerOffOrToggleCommand(HdmiCecMessage message) {
         byte[] params = message.getParams();
         return message.getOpcode() == Constants.MESSAGE_USER_CONTROL_PRESSED
                 && (params[0] == HdmiCecKeycode.CEC_KEYCODE_POWER
@@ -429,9 +428,7 @@
         } else if (message.getDestination() != Constants.ADDR_BROADCAST &&
                 message.getSource() != Constants.ADDR_UNREGISTERED) {
             Slog.v(TAG, "Wrong direct vendor command. Replying with <Feature Abort>");
-            mService.sendCecCommand(HdmiCecMessageBuilder.buildFeatureAbortCommand(mAddress,
-                    message.getSource(), Constants.MESSAGE_VENDOR_COMMAND_WITH_ID,
-                    Constants.ABORT_UNRECOGNIZED_MODE));
+            mService.maySendFeatureAbortCommand(message, Constants.ABORT_UNRECOGNIZED_OPCODE);
         } else {
             Slog.v(TAG, "Wrong broadcast vendor command. Ignoring");
         }
@@ -444,28 +441,32 @@
     }
 
     protected boolean handleRecordTvScreen(HdmiCecMessage message) {
-        // The default behavior of <Record TV Screen> is replying <Feature Abort> with "Refused".
-        mService.sendCecCommand(HdmiCecMessageBuilder.buildFeatureAbortCommand(mAddress,
-                message.getSource(), message.getOpcode(), Constants.ABORT_REFUSED));
+        // The default behavior of <Record TV Screen> is replying <Feature Abort> with
+        // "Cannot provide source".
+        mService.maySendFeatureAbortCommand(message, Constants.ABORT_CANNOT_PROVIDE_SOURCE);
         return true;
     }
 
+    protected boolean handleTimerClearedStatus(HdmiCecMessage message) {
+        return false;
+    }
+
     @ServiceThreadOnly
-    final void handleAddressAllocated(int logicalAddress, boolean fromBootup) {
+    final void handleAddressAllocated(int logicalAddress, int reason) {
         assertRunOnServiceThread();
         mAddress = mPreferredAddress = logicalAddress;
-        onAddressAllocated(logicalAddress, fromBootup);
+        onAddressAllocated(logicalAddress, reason);
         setPreferredAddress(logicalAddress);
     }
 
     @ServiceThreadOnly
-    HdmiCecDeviceInfo getDeviceInfo() {
+    HdmiDeviceInfo getDeviceInfo() {
         assertRunOnServiceThread();
         return mDeviceInfo;
     }
 
     @ServiceThreadOnly
-    void setDeviceInfo(HdmiCecDeviceInfo info) {
+    void setDeviceInfo(HdmiDeviceInfo info) {
         assertRunOnServiceThread();
         mDeviceInfo = info;
     }
@@ -485,7 +486,7 @@
     }
 
     @ServiceThreadOnly
-    void addAndStartAction(final FeatureAction action) {
+    void addAndStartAction(final HdmiCecFeatureAction action) {
         assertRunOnServiceThread();
         if (mService.isPowerStandbyOrTransient()) {
             Slog.w(TAG, "Skip the action during Standby: " + action);
@@ -497,9 +498,9 @@
 
     // See if we have an action of a given type in progress.
     @ServiceThreadOnly
-    <T extends FeatureAction> boolean hasAction(final Class<T> clazz) {
+    <T extends HdmiCecFeatureAction> boolean hasAction(final Class<T> clazz) {
         assertRunOnServiceThread();
-        for (FeatureAction action : mActions) {
+        for (HdmiCecFeatureAction action : mActions) {
             if (action.getClass().equals(clazz)) {
                 return true;
             }
@@ -509,10 +510,10 @@
 
     // Returns all actions matched with given class type.
     @ServiceThreadOnly
-    <T extends FeatureAction> List<T> getActions(final Class<T> clazz) {
+    <T extends HdmiCecFeatureAction> List<T> getActions(final Class<T> clazz) {
         assertRunOnServiceThread();
         List<T> actions = Collections.<T>emptyList();
-        for (FeatureAction action : mActions) {
+        for (HdmiCecFeatureAction action : mActions) {
             if (action.getClass().equals(clazz)) {
                 if (actions.isEmpty()) {
                     actions = new ArrayList<T>();
@@ -524,12 +525,12 @@
     }
 
     /**
-     * Remove the given {@link FeatureAction} object from the action queue.
+     * Remove the given {@link HdmiCecFeatureAction} object from the action queue.
      *
-     * @param action {@link FeatureAction} to remove
+     * @param action {@link HdmiCecFeatureAction} to remove
      */
     @ServiceThreadOnly
-    void removeAction(final FeatureAction action) {
+    void removeAction(final HdmiCecFeatureAction action) {
         assertRunOnServiceThread();
         action.finish(false);
         mActions.remove(action);
@@ -538,19 +539,19 @@
 
     // Remove all actions matched with the given Class type.
     @ServiceThreadOnly
-    <T extends FeatureAction> void removeAction(final Class<T> clazz) {
+    <T extends HdmiCecFeatureAction> void removeAction(final Class<T> clazz) {
         assertRunOnServiceThread();
         removeActionExcept(clazz, null);
     }
 
     // Remove all actions matched with the given Class type besides |exception|.
     @ServiceThreadOnly
-    <T extends FeatureAction> void removeActionExcept(final Class<T> clazz,
-            final FeatureAction exception) {
+    <T extends HdmiCecFeatureAction> void removeActionExcept(final Class<T> clazz,
+            final HdmiCecFeatureAction exception) {
         assertRunOnServiceThread();
-        Iterator<FeatureAction> iter = mActions.iterator();
+        Iterator<HdmiCecFeatureAction> iter = mActions.iterator();
         while (iter.hasNext()) {
-            FeatureAction action = iter.next();
+            HdmiCecFeatureAction action = iter.next();
             if (action != exception && action.getClass().equals(clazz)) {
                 action.finish(false);
                 iter.remove();
@@ -603,7 +604,7 @@
         setActiveSource(newActive.logicalAddress, newActive.physicalAddress);
     }
 
-    void setActiveSource(HdmiCecDeviceInfo info) {
+    void setActiveSource(HdmiDeviceInfo info) {
         setActiveSource(info.getLogicalAddress(), info.getPhysicalAddress());
     }
 
@@ -697,9 +698,9 @@
 
         // If all actions are not cleared in DEVICE_CLEANUP_TIMEOUT, enforce to finish them.
         // onCleard will be called at the last action's finish method.
-        Iterator<FeatureAction> iter = mActions.iterator();
+        Iterator<HdmiCecFeatureAction> iter = mActions.iterator();
         while (iter.hasNext()) {
-            FeatureAction action = iter.next();
+            HdmiCecFeatureAction action = iter.next();
             action.finish(false);
             iter.remove();
         }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index a66d78c..ae7fd82 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -16,7 +16,7 @@
 
 package com.android.server.hdmi;
 
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.IHdmiControlCallback;
 import android.os.RemoteException;
@@ -34,15 +34,20 @@
     private boolean mIsActiveSource = false;
 
     HdmiCecLocalDevicePlayback(HdmiControlService service) {
-        super(service, HdmiCecDeviceInfo.DEVICE_PLAYBACK);
+        super(service, HdmiDeviceInfo.DEVICE_PLAYBACK);
     }
 
     @Override
     @ServiceThreadOnly
-    protected void onAddressAllocated(int logicalAddress, boolean fromBootup) {
+    protected void onAddressAllocated(int logicalAddress, int reason) {
         assertRunOnServiceThread();
         mService.sendCecCommand(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
                 mAddress, mService.getPhysicalAddress(), mDeviceType));
+        if (reason == HdmiControlService.INITIATED_BY_SCREEN_ON) {
+            oneTouchPlay(new IHdmiControlCallback.Stub() {
+                @Override public void onComplete(int result) throws RemoteException {}
+            });
+        }
     }
 
     @Override
@@ -135,7 +140,7 @@
         if (physicalAddress != mService.getPhysicalAddress()) {
             mIsActiveSource = false;
             if (mService.isPowerOnOrTransient()) {
-                mService.standby();
+                mService.nap();
             }
             return true;
         }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index eda7b18..fb4fa7f 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -16,15 +16,21 @@
 
 package com.android.server.hdmi;
 
+import static android.hardware.hdmi.HdmiControlManager.CLEAR_TIMER_STATUS_CEC_DISABLE;
+import static android.hardware.hdmi.HdmiControlManager.CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION;
+import static android.hardware.hdmi.HdmiControlManager.CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE;
 import static android.hardware.hdmi.HdmiControlManager.ONE_TOUCH_RECORD_CEC_DISABLED;
 import static android.hardware.hdmi.HdmiControlManager.ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION;
 import static android.hardware.hdmi.HdmiControlManager.ONE_TOUCH_RECORD_FAIL_TO_RECORD_DISPLAYED_SCREEN;
-import static android.hardware.hdmi.HdmiControlManager.TIME_RECORDING_RESULT_EXTRA_CEC_DISABLED;
-import static android.hardware.hdmi.HdmiControlManager.TIME_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION;
-import static android.hardware.hdmi.HdmiControlManager.TIME_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE;
+import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED;
+import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION;
+import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE;
+import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_ANALOGUE;
+import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_DIGITAL;
+import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_EXTERNAL;
 
 import android.content.Intent;
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiRecordSources;
 import android.hardware.hdmi.HdmiTimerRecordSources;
@@ -35,17 +41,21 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings.Global;
+import android.util.ArraySet;
 import android.util.Slog;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.server.hdmi.DeviceDiscoveryAction.DeviceDiscoveryCallback;
 import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
+import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
 
 import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 
@@ -84,15 +94,15 @@
 
     // Copy of mDeviceInfos to guarantee thread-safety.
     @GuardedBy("mLock")
-    private List<HdmiCecDeviceInfo> mSafeAllDeviceInfos = Collections.emptyList();
+    private List<HdmiDeviceInfo> mSafeAllDeviceInfos = Collections.emptyList();
     // All external cec input(source) devices. Does not include system audio device.
     @GuardedBy("mLock")
-    private List<HdmiCecDeviceInfo> mSafeExternalInputs = Collections.emptyList();
+    private List<HdmiDeviceInfo> mSafeExternalInputs = Collections.emptyList();
 
     // Map-like container of all cec devices including local ones.
     // A logical address of device is used as key of container.
     // This is not thread-safe. For external purpose use mSafeDeviceInfos.
-    private final SparseArray<HdmiCecDeviceInfo> mDeviceInfos = new SparseArray<>();
+    private final SparseArray<HdmiDeviceInfo> mDeviceInfos = new SparseArray<>();
 
     // If true, TV going to standby mode puts other devices also to standby.
     private boolean mAutoDeviceOff;
@@ -100,23 +110,32 @@
     // If true, TV wakes itself up when receiving <Text/Image View On>.
     private boolean mAutoWakeup;
 
+    private final HdmiCecStandbyModeHandler mStandbyHandler;
+
+    // Set of physical addresses of CEC switches on the CEC bus. Managed independently from
+    // other CEC devices since they might not have logical address.
+    private final ArraySet<Integer> mCecSwitches = new ArraySet<Integer>();
+
     HdmiCecLocalDeviceTv(HdmiControlService service) {
-        super(service, HdmiCecDeviceInfo.DEVICE_TV);
+        super(service, HdmiDeviceInfo.DEVICE_TV);
         mPrevPortId = Constants.INVALID_PORT_ID;
         mAutoDeviceOff = mService.readBooleanSetting(Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED,
                 true);
         mAutoWakeup = mService.readBooleanSetting(Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED, true);
+        mStandbyHandler = new HdmiCecStandbyModeHandler(service, this);
     }
 
     @Override
     @ServiceThreadOnly
-    protected void onAddressAllocated(int logicalAddress, boolean fromBootup) {
+    protected void onAddressAllocated(int logicalAddress, int reason) {
         assertRunOnServiceThread();
         mService.sendCecCommand(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
                 mAddress, mService.getPhysicalAddress(), mDeviceType));
         mService.sendCecCommand(HdmiCecMessageBuilder.buildDeviceVendorIdCommand(
                 mAddress, mService.getVendorId()));
-        launchRoutingControl(fromBootup);
+        mCecSwitches.add(mService.getPhysicalAddress());  // TV is a CEC switch too.
+        launchRoutingControl(reason != HdmiControlService.INITIATED_BY_ENABLE_CEC &&
+                reason != HdmiControlService.INITIATED_BY_BOOT_UP);
         launchDeviceDiscovery();
     }
 
@@ -135,6 +154,16 @@
         SystemProperties.set(Constants.PROPERTY_PREFERRED_ADDRESS_TV, String.valueOf(addr));
     }
 
+    @Override
+    @ServiceThreadOnly
+    boolean dispatchMessage(HdmiCecMessage message) {
+        assertRunOnServiceThread();
+        if (mService.isPowerStandby() && mStandbyHandler.handleCommand(message)) {
+            return true;
+        }
+        return super.onMessage(message);
+    }
+
     /**
      * Performs the action 'device select', or 'one touch play' initiated by TV.
      *
@@ -144,6 +173,11 @@
     @ServiceThreadOnly
     void deviceSelect(int targetAddress, IHdmiControlCallback callback) {
         assertRunOnServiceThread();
+        ActiveSource active = getActiveSource();
+        if (active.isValid() && targetAddress == active.logicalAddress) {
+            invokeCallback(callback, HdmiControlManager.RESULT_SUCCESS);
+            return;
+        }
         if (targetAddress == Constants.ADDR_INTERNAL) {
             handleSelectInternalSource();
             // Switching to internal source is always successful even when CEC control is disabled.
@@ -153,14 +187,14 @@
             return;
         }
         if (!mService.isControlEnabled()) {
-            HdmiCecDeviceInfo info = getDeviceInfo(targetAddress);
+            HdmiDeviceInfo info = getDeviceInfo(targetAddress);
             if (info != null) {
                 setActiveSource(info);
             }
             invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE);
             return;
         }
-        HdmiCecDeviceInfo targetDevice = getDeviceInfo(targetAddress);
+        HdmiDeviceInfo targetDevice = getDeviceInfo(targetAddress);
         if (targetDevice == null) {
             invokeCallback(callback, HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
             return;
@@ -245,10 +279,10 @@
         // Show OSD port change banner
         if (notifyInputChange) {
             ActiveSource activeSource = getActiveSource();
-            HdmiCecDeviceInfo info = getDeviceInfo(activeSource.logicalAddress);
+            HdmiDeviceInfo info = getDeviceInfo(activeSource.logicalAddress);
             if (info == null) {
-                info = new HdmiCecDeviceInfo(Constants.ADDR_INVALID, path, portId,
-                        HdmiCecDeviceInfo.DEVICE_RESERVED, 0, null);
+                info = new HdmiDeviceInfo(Constants.ADDR_INVALID, path, portId,
+                        HdmiDeviceInfo.DEVICE_RESERVED, 0, null);
             }
             mService.invokeInputChangeListener(info);
         }
@@ -354,7 +388,7 @@
         if (portId != Constants.INVALID_PORT_ID) {
             // TODO: Do this only if TV is not showing multiview like PIP/PAP.
 
-            HdmiCecDeviceInfo inactiveSource = getDeviceInfo(message.getSource());
+            HdmiDeviceInfo inactiveSource = getDeviceInfo(message.getSource());
             if (inactiveSource == null) {
                 return true;
             }
@@ -400,15 +434,27 @@
     @ServiceThreadOnly
     protected boolean handleReportPhysicalAddress(HdmiCecMessage message) {
         assertRunOnServiceThread();
+        int path = HdmiUtils.twoBytesToInt(message.getParams());
+        int address = message.getSource();
+
+        // Build cec switch list with pure CEC switch, AVR.
+        if (address == Constants.ADDR_UNREGISTERED) {
+            int type = message.getParams()[2];
+            if (type == HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH) {
+                mCecSwitches.add(path);
+                updateSafeDeviceInfoList();
+                return true;  // Pure switch does not need further processing. Return here.
+            } else if (type == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) {
+                mCecSwitches.add(path);
+            }
+        }
+
         // Ignore if [Device Discovery Action] is going on.
         if (hasAction(DeviceDiscoveryAction.class)) {
-            Slog.i(TAG, "Ignore unrecognizable <Report Physical Address> "
-                    + "because Device Discovery Action is on-going:" + message);
+            Slog.i(TAG, "Ignored while Device Discovery Action is in progress: " + message);
             return true;
         }
 
-        int path = HdmiUtils.twoBytesToInt(message.getParams());
-        int address = message.getSource();
         if (!isInDeviceList(path, address)) {
             handleNewDeviceAtTheTailOfActivePath(path);
         }
@@ -526,7 +572,7 @@
     @ServiceThreadOnly
     protected boolean handleSetOsdName(HdmiCecMessage message) {
         int source = message.getSource();
-        HdmiCecDeviceInfo deviceInfo = getDeviceInfo(source);
+        HdmiDeviceInfo deviceInfo = getDeviceInfo(source);
         // If the device is not in device list, ignore it.
         if (deviceInfo == null) {
             Slog.e(TAG, "No source device info for <Set Osd Name>." + message);
@@ -545,7 +591,7 @@
             return true;
         }
 
-        addCecDevice(new HdmiCecDeviceInfo(deviceInfo.getLogicalAddress(),
+        addCecDevice(new HdmiDeviceInfo(deviceInfo.getLogicalAddress(),
                 deviceInfo.getPhysicalAddress(), deviceInfo.getPortId(),
                 deviceInfo.getDeviceType(), deviceInfo.getVendorId(), osdName));
         return true;
@@ -558,8 +604,8 @@
         DeviceDiscoveryAction action = new DeviceDiscoveryAction(this,
                 new DeviceDiscoveryCallback() {
                     @Override
-                    public void onDeviceDiscoveryDone(List<HdmiCecDeviceInfo> deviceInfos) {
-                        for (HdmiCecDeviceInfo info : deviceInfos) {
+                    public void onDeviceDiscoveryDone(List<HdmiDeviceInfo> deviceInfos) {
+                        for (HdmiDeviceInfo info : deviceInfos) {
                             addCecDevice(info);
                         }
 
@@ -592,8 +638,8 @@
     @ServiceThreadOnly
     private void clearDeviceInfoList() {
         assertRunOnServiceThread();
-        for (HdmiCecDeviceInfo info : mSafeExternalInputs) {
-            mService.invokeDeviceEventListeners(info, false);
+        for (HdmiDeviceInfo info : mSafeExternalInputs) {
+            invokeDeviceEventListener(info, false);
         }
         mDeviceInfos.clear();
         updateSafeDeviceInfoList();
@@ -608,7 +654,7 @@
             invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE);
             return;
         }
-        HdmiCecDeviceInfo avr = getAvrDeviceInfo();
+        HdmiDeviceInfo avr = getAvrDeviceInfo();
         if (avr == null) {
             setSystemAudioMode(false, true);
             invokeCallback(callback, HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
@@ -712,7 +758,7 @@
     @ServiceThreadOnly
     private void startArcAction(boolean enabled) {
         assertRunOnServiceThread();
-        HdmiCecDeviceInfo info = getAvrDeviceInfo();
+        HdmiDeviceInfo info = getAvrDeviceInfo();
         if (info == null) {
             return;
         }
@@ -768,7 +814,7 @@
         // Remove existing volume action.
         removeAction(VolumeControlAction.class);
 
-        HdmiCecDeviceInfo avr = getAvrDeviceInfo();
+        HdmiDeviceInfo avr = getAvrDeviceInfo();
         addAndStartAction(VolumeControlAction.ofVolumeChange(this, avr.getLogicalAddress(),
                 cecVolume, delta > 0));
     }
@@ -782,18 +828,10 @@
 
         // Remove existing volume action.
         removeAction(VolumeControlAction.class);
-        HdmiCecDeviceInfo avr = getAvrDeviceInfo();
+        HdmiDeviceInfo avr = getAvrDeviceInfo();
         addAndStartAction(VolumeControlAction.ofMute(this, avr.getLogicalAddress(), mute));
     }
 
-    private boolean isSystemAudioOn() {
-
-
-        synchronized (mLock) {
-            return mSystemAudioActivated;
-        }
-    }
-
     @Override
     @ServiceThreadOnly
     protected boolean handleInitiateArc(HdmiCecMessage message) {
@@ -865,6 +903,14 @@
         return true;
     }
 
+    @Override
+    protected boolean handleTimerClearedStatus(HdmiCecMessage message) {
+        byte[] params = message.getParams();
+        int timerClearedStatusData = params[0] & 0xFF;
+        announceTimerRecordingResult(timerClearedStatusData);
+        return true;
+    }
+
     void announceOneTouchRecordResult(int result) {
         mService.invokeOneTouchRecordResult(result);
     }
@@ -873,6 +919,10 @@
         mService.invokeTimerRecordingResult(result);
     }
 
+    void announceClearTimerRecordingResult(int result) {
+        mService.invokeClearTimerRecordingResult(result);
+    }
+
     private boolean isMessageForSystemAudio(HdmiCecMessage message) {
         if (message.getSource() != Constants.ADDR_AUDIO_SYSTEM
                 || message.getDestination() != Constants.ADDR_TV
@@ -884,19 +934,19 @@
     }
 
     /**
-     * Add a new {@link HdmiCecDeviceInfo}. It returns old device info which has the same
+     * Add a new {@link HdmiDeviceInfo}. It returns old device info which has the same
      * logical address as new device info's.
      *
      * <p>Declared as package-private. accessed by {@link HdmiControlService} only.
      *
-     * @param deviceInfo a new {@link HdmiCecDeviceInfo} to be added.
-     * @return {@code null} if it is new device. Otherwise, returns old {@HdmiCecDeviceInfo}
+     * @param deviceInfo a new {@link HdmiDeviceInfo} to be added.
+     * @return {@code null} if it is new device. Otherwise, returns old {@HdmiDeviceInfo}
      *         that has the same logical address as new one has.
      */
     @ServiceThreadOnly
-    private HdmiCecDeviceInfo addDeviceInfo(HdmiCecDeviceInfo deviceInfo) {
+    private HdmiDeviceInfo addDeviceInfo(HdmiDeviceInfo deviceInfo) {
         assertRunOnServiceThread();
-        HdmiCecDeviceInfo oldDeviceInfo = getDeviceInfo(deviceInfo.getLogicalAddress());
+        HdmiDeviceInfo oldDeviceInfo = getDeviceInfo(deviceInfo.getLogicalAddress());
         if (oldDeviceInfo != null) {
             removeDeviceInfo(deviceInfo.getLogicalAddress());
         }
@@ -907,17 +957,17 @@
 
     /**
      * Remove a device info corresponding to the given {@code logicalAddress}.
-     * It returns removed {@link HdmiCecDeviceInfo} if exists.
+     * It returns removed {@link HdmiDeviceInfo} if exists.
      *
      * <p>Declared as package-private. accessed by {@link HdmiControlService} only.
      *
      * @param logicalAddress logical address of device to be removed
-     * @return removed {@link HdmiCecDeviceInfo} it exists. Otherwise, returns {@code null}
+     * @return removed {@link HdmiDeviceInfo} it exists. Otherwise, returns {@code null}
      */
     @ServiceThreadOnly
-    private HdmiCecDeviceInfo removeDeviceInfo(int logicalAddress) {
+    private HdmiDeviceInfo removeDeviceInfo(int logicalAddress) {
         assertRunOnServiceThread();
-        HdmiCecDeviceInfo deviceInfo = mDeviceInfos.get(logicalAddress);
+        HdmiDeviceInfo deviceInfo = mDeviceInfos.get(logicalAddress);
         if (deviceInfo != null) {
             mDeviceInfos.remove(logicalAddress);
         }
@@ -926,20 +976,21 @@
     }
 
     /**
-     * Return a list of all {@link HdmiCecDeviceInfo}.
+     * Return a list of all {@link HdmiDeviceInfo}.
      *
      * <p>Declared as package-private. accessed by {@link HdmiControlService} only.
-     * This is not thread-safe. For thread safety, call {@link #getSafeDeviceInfoList(boolean)}.
+     * This is not thread-safe. For thread safety, call {@link #getSafeExternalInputs} which
+     * does not include local device.
      */
     @ServiceThreadOnly
-    List<HdmiCecDeviceInfo> getDeviceInfoList(boolean includelLocalDevice) {
+    List<HdmiDeviceInfo> getDeviceInfoList(boolean includelLocalDevice) {
         assertRunOnServiceThread();
         if (includelLocalDevice) {
             return HdmiUtils.sparseArrayToList(mDeviceInfos);
         } else {
-            ArrayList<HdmiCecDeviceInfo> infoList = new ArrayList<>();
+            ArrayList<HdmiDeviceInfo> infoList = new ArrayList<>();
             for (int i = 0; i < mDeviceInfos.size(); ++i) {
-                HdmiCecDeviceInfo info = mDeviceInfos.valueAt(i);
+                HdmiDeviceInfo info = mDeviceInfos.valueAt(i);
                 if (!isLocalDeviceAddress(info.getLogicalAddress())) {
                     infoList.add(info);
                 }
@@ -951,7 +1002,7 @@
     /**
      * Return external input devices.
      */
-    List<HdmiCecDeviceInfo> getSafeExternalInputs() {
+    List<HdmiDeviceInfo> getSafeExternalInputs() {
         synchronized (mLock) {
             return mSafeExternalInputs;
         }
@@ -960,8 +1011,8 @@
     @ServiceThreadOnly
     private void updateSafeDeviceInfoList() {
         assertRunOnServiceThread();
-        List<HdmiCecDeviceInfo> copiedDevices = HdmiUtils.sparseArrayToList(mDeviceInfos);
-        List<HdmiCecDeviceInfo> externalInputs = getInputDevices();
+        List<HdmiDeviceInfo> copiedDevices = HdmiUtils.sparseArrayToList(mDeviceInfos);
+        List<HdmiDeviceInfo> externalInputs = getInputDevices();
         synchronized (mLock) {
             mSafeAllDeviceInfos = copiedDevices;
             mSafeExternalInputs = externalInputs;
@@ -974,20 +1025,56 @@
      * <p>Note that this effectively excludes non-source devices like system audio,
      * secondary TV.
      */
-    private List<HdmiCecDeviceInfo> getInputDevices() {
-        ArrayList<HdmiCecDeviceInfo> infoList = new ArrayList<>();
+    private List<HdmiDeviceInfo> getInputDevices() {
+        ArrayList<HdmiDeviceInfo> infoList = new ArrayList<>();
         for (int i = 0; i < mDeviceInfos.size(); ++i) {
-            HdmiCecDeviceInfo info = mDeviceInfos.valueAt(i);
+            HdmiDeviceInfo info = mDeviceInfos.valueAt(i);
             if (isLocalDeviceAddress(i)) {
                 continue;
             }
-            if (info.isSourceType()) {
+            if (info.isSourceType() && !hideDevicesBehindLegacySwitch(info)) {
                 infoList.add(info);
             }
         }
         return infoList;
     }
 
+    // Check if we are hiding CEC devices connected to a legacy (non-CEC) switch.
+    // Returns true if the policy is set to true, and the device to check does not have
+    // a parent CEC device (which should be the CEC-enabled switch) in the list.
+    private boolean hideDevicesBehindLegacySwitch(HdmiDeviceInfo info) {
+        return HdmiConfig.HIDE_DEVICES_BEHIND_LEGACY_SWITCH
+                && !isConnectedToCecSwitch(info.getPhysicalAddress(), mCecSwitches);
+    }
+
+    private static boolean isConnectedToCecSwitch(int path, Collection<Integer> switches) {
+        for (int switchPath : switches) {
+            if (isParentPath(switchPath, path)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean isParentPath(int parentPath, int childPath) {
+        // (A000, AB00) (AB00, ABC0), (ABC0, ABCD)
+        // If child's last non-zero nibble is removed, the result equals to the parent.
+        for (int i = 0; i <= 12; i += 4) {
+            int nibble = (childPath >> i) & 0xF;
+            if (nibble != 0) {
+                int parentNibble = (parentPath >> i) & 0xF;
+                return parentNibble == 0 && (childPath >> i+4) == (parentPath >> i+4);
+            }
+        }
+        return false;
+    }
+
+    private void invokeDeviceEventListener(HdmiDeviceInfo info, boolean activated) {
+        if (!hideDevicesBehindLegacySwitch(info)) {
+            mService.invokeDeviceEventListeners(info, activated);
+        }
+    }
+
     @ServiceThreadOnly
     private boolean isLocalDeviceAddress(int address) {
         assertRunOnServiceThread();
@@ -1000,23 +1087,23 @@
     }
 
     @ServiceThreadOnly
-    HdmiCecDeviceInfo getAvrDeviceInfo() {
+    HdmiDeviceInfo getAvrDeviceInfo() {
         assertRunOnServiceThread();
         return getDeviceInfo(Constants.ADDR_AUDIO_SYSTEM);
     }
 
     /**
-     * Return a {@link HdmiCecDeviceInfo} corresponding to the given {@code logicalAddress}.
+     * Return a {@link HdmiDeviceInfo} corresponding to the given {@code logicalAddress}.
      *
      * <p>Declared as package-private. accessed by {@link HdmiControlService} only.
      * This is not thread-safe. For thread safety, call {@link #getSafeDeviceInfo(int)}.
      *
      * @param logicalAddress logical address to be retrieved
-     * @return {@link HdmiCecDeviceInfo} matched with the given {@code logicalAddress}.
+     * @return {@link HdmiDeviceInfo} matched with the given {@code logicalAddress}.
      *         Returns null if no logical address matched
      */
     @ServiceThreadOnly
-    HdmiCecDeviceInfo getDeviceInfo(int logicalAddress) {
+    HdmiDeviceInfo getDeviceInfo(int logicalAddress) {
         assertRunOnServiceThread();
         return mDeviceInfos.get(logicalAddress);
     }
@@ -1025,7 +1112,7 @@
         return getSafeAvrDeviceInfo() != null;
     }
 
-    HdmiCecDeviceInfo getSafeAvrDeviceInfo() {
+    HdmiDeviceInfo getSafeAvrDeviceInfo() {
         return getSafeDeviceInfo(Constants.ADDR_AUDIO_SYSTEM);
     }
 
@@ -1033,10 +1120,10 @@
      * Thread safe version of {@link #getDeviceInfo(int)}.
      *
      * @param logicalAddress logical address to be retrieved
-     * @return {@link HdmiCecDeviceInfo} matched with the given {@code logicalAddress}.
+     * @return {@link HdmiDeviceInfo} matched with the given {@code logicalAddress}.
      *         Returns null if no logical address matched
      */
-    HdmiCecDeviceInfo getSafeDeviceInfo(int logicalAddress) {
+    HdmiDeviceInfo getSafeDeviceInfo(int logicalAddress) {
         synchronized (mLock) {
             return mSafeAllDeviceInfos.get(logicalAddress);
         }
@@ -1049,14 +1136,14 @@
      * @param info device info of a new device.
      */
     @ServiceThreadOnly
-    final void addCecDevice(HdmiCecDeviceInfo info) {
+    final void addCecDevice(HdmiDeviceInfo info) {
         assertRunOnServiceThread();
         addDeviceInfo(info);
         if (info.getLogicalAddress() == mAddress) {
             // The addition of TV device itself should not be notified.
             return;
         }
-        mService.invokeDeviceEventListeners(info, true);
+        invokeDeviceEventListener(info, true);
     }
 
     /**
@@ -1067,10 +1154,10 @@
     @ServiceThreadOnly
     final void removeCecDevice(int address) {
         assertRunOnServiceThread();
-        HdmiCecDeviceInfo info = removeDeviceInfo(address);
+        HdmiDeviceInfo info = removeDeviceInfo(address);
 
         mCecMessageCache.flushMessagesFrom(address);
-        mService.invokeDeviceEventListeners(info, false);
+        invokeDeviceEventListener(info, false);
     }
 
     @ServiceThreadOnly
@@ -1117,17 +1204,17 @@
     }
 
     /**
-     * Returns the {@link HdmiCecDeviceInfo} instance whose physical address matches
+     * Returns the {@link HdmiDeviceInfo} instance whose physical address matches
      * the given routing path. CEC devices use routing path for its physical address to
      * describe the hierarchy of the devices in the network.
      *
      * @param path routing path or physical address
-     * @return {@link HdmiCecDeviceInfo} if the matched info is found; otherwise null
+     * @return {@link HdmiDeviceInfo} if the matched info is found; otherwise null
      */
     @ServiceThreadOnly
-    final HdmiCecDeviceInfo getDeviceInfoByPath(int path) {
+    final HdmiDeviceInfo getDeviceInfoByPath(int path) {
         assertRunOnServiceThread();
-        for (HdmiCecDeviceInfo info : getDeviceInfoList(false)) {
+        for (HdmiDeviceInfo info : getDeviceInfoList(false)) {
             if (info.getPhysicalAddress() == path) {
                 return info;
             }
@@ -1147,7 +1234,7 @@
     @ServiceThreadOnly
     boolean isInDeviceList(int logicalAddress, int physicalAddress) {
         assertRunOnServiceThread();
-        HdmiCecDeviceInfo device = getDeviceInfo(logicalAddress);
+        HdmiDeviceInfo device = getDeviceInfo(logicalAddress);
         if (device == null) {
             return false;
         }
@@ -1159,6 +1246,9 @@
     void onHotplug(int portId, boolean connected) {
         assertRunOnServiceThread();
 
+        if (!connected) {
+            removeCecSwitches(portId);
+        }
         // Tv device will have permanent HotplugDetectionAction.
         List<HotplugDetectionAction> hotplugActions = getActions(HotplugDetectionAction.class);
         if (!hotplugActions.isEmpty()) {
@@ -1169,6 +1259,16 @@
         }
     }
 
+    private void removeCecSwitches(int portId) {
+        Iterator<Integer> it = mCecSwitches.iterator();
+        while (!it.hasNext()) {
+            int path = it.next();
+            if (pathToPortId(path) == portId) {
+                it.remove();
+            }
+        }
+    }
+
     @ServiceThreadOnly
     void setAutoDeviceOff(boolean enabled) {
         assertRunOnServiceThread();
@@ -1183,6 +1283,12 @@
         mService.writeBooleanSetting(Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED, enabled);
     }
 
+    @ServiceThreadOnly
+    boolean getAutoWakeup() {
+        assertRunOnServiceThread();
+        return mAutoWakeup;
+    }
+
     @Override
     @ServiceThreadOnly
     protected void disableDevice(boolean initiatedByCec, PendingActionClearedCallback callback) {
@@ -1194,8 +1300,9 @@
         //     LocalDeviceTv.onAddressAllocated() -> launchDeviceDiscovery().
         removeAction(DeviceDiscoveryAction.class);
         removeAction(HotplugDetectionAction.class);
-        // Remove one touch record action.
+        // Remove recording actions.
         removeAction(OneTouchRecordAction.class);
+        removeAction(TimerRecordingAction.class);
 
         disableSystemAudioIfExist();
         disableArcIfExist();
@@ -1225,7 +1332,7 @@
     @ServiceThreadOnly
     private void disableArcIfExist() {
         assertRunOnServiceThread();
-        HdmiCecDeviceInfo avr = getAvrDeviceInfo();
+        HdmiDeviceInfo avr = getAvrDeviceInfo();
         if (avr == null) {
             return;
         }
@@ -1315,10 +1422,10 @@
     }
 
     private boolean checkRecorder(int recorderAddress) {
-        HdmiCecDeviceInfo device = getDeviceInfo(recorderAddress);
+        HdmiDeviceInfo device = getDeviceInfo(recorderAddress);
         return (device != null)
                 && (HdmiUtils.getTypeFromAddress(recorderAddress)
-                        == HdmiCecDeviceInfo.DEVICE_RECORDER);
+                        == HdmiDeviceInfo.DEVICE_RECORDER);
     }
 
     private boolean checkRecordSource(byte[] recordSource) {
@@ -1330,21 +1437,21 @@
         assertRunOnServiceThread();
         if (!mService.isControlEnabled()) {
             Slog.w(TAG, "Can not start one touch record. CEC control is disabled.");
-            announceTimerRecordingResult(TIME_RECORDING_RESULT_EXTRA_CEC_DISABLED);
+            announceTimerRecordingResult(TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED);
             return;
         }
 
         if (!checkRecorder(recorderAddress)) {
             Slog.w(TAG, "Invalid recorder address:" + recorderAddress);
             announceTimerRecordingResult(
-                    TIME_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
+                    TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
             return;
         }
 
         if (!checkTimerRecordingSource(sourceType, recordSource)) {
             Slog.w(TAG, "Invalid record source." + Arrays.toString(recordSource));
             announceTimerRecordingResult(
-                    TIME_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE);
+                    TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE);
             return;
         }
 
@@ -1362,7 +1469,56 @@
     @ServiceThreadOnly
     void clearTimerRecording(int recorderAddress, int sourceType, byte[] recordSource) {
         assertRunOnServiceThread();
+        if (!mService.isControlEnabled()) {
+            Slog.w(TAG, "Can not start one touch record. CEC control is disabled.");
+            announceClearTimerRecordingResult(CLEAR_TIMER_STATUS_CEC_DISABLE);
+            return;
+        }
 
-        // TODO: implement this.
+        if (!checkRecorder(recorderAddress)) {
+            Slog.w(TAG, "Invalid recorder address:" + recorderAddress);
+            announceClearTimerRecordingResult(CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION);
+            return;
+        }
+
+        if (!checkTimerRecordingSource(sourceType, recordSource)) {
+            Slog.w(TAG, "Invalid record source." + Arrays.toString(recordSource));
+            announceClearTimerRecordingResult(CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
+            return;
+        }
+
+        sendClearTimerMessage(recorderAddress, sourceType, recordSource);
+    }
+
+    private void sendClearTimerMessage(int recorderAddress, int sourceType, byte[] recordSource) {
+        HdmiCecMessage message = null;
+        switch (sourceType) {
+            case TIMER_RECORDING_TYPE_DIGITAL:
+                message = HdmiCecMessageBuilder.buildClearDigitalTimer(mAddress, recorderAddress,
+                        recordSource);
+                break;
+            case TIMER_RECORDING_TYPE_ANALOGUE:
+                message = HdmiCecMessageBuilder.buildClearAnalogueTimer(mAddress, recorderAddress,
+                        recordSource);
+                break;
+            case TIMER_RECORDING_TYPE_EXTERNAL:
+                message = HdmiCecMessageBuilder.buildClearExternalTimer(mAddress, recorderAddress,
+                        recordSource);
+                break;
+            default:
+                Slog.w(TAG, "Invalid source type:" + recorderAddress);
+                announceClearTimerRecordingResult(CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
+                return;
+
+        }
+        mService.sendCecCommand(message, new SendMessageCallback() {
+            @Override
+            public void onSendCompleted(int error) {
+                if (error != Constants.SEND_RESULT_SUCCESS) {
+                    announceClearTimerRecordingResult(
+                            CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
+                }
+            }
+        });
     }
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessage.java b/services/core/java/com/android/server/hdmi/HdmiCecMessage.java
index 970568a..433e93f 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessage.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessage.java
@@ -16,9 +16,6 @@
 
 package com.android.server.hdmi;
 
-import android.os.Parcel;
-import android.os.Parcelable;
-
 import libcore.util.EmptyArray;
 
 import java.util.Arrays;
@@ -28,12 +25,9 @@
  * HDMI cable to communicate with one another. A message is defined by its
  * source and destination address, command (or opcode), and optional parameters.
  */
-public final class HdmiCecMessage implements Parcelable {
-
+public final class HdmiCecMessage {
     public static final byte[] EMPTY_PARAM = EmptyArray.BYTE;
 
-    private static final int MAX_MESSAGE_LENGTH = 16;
-
     private final int mSource;
     private final int mDestination;
 
@@ -91,53 +85,6 @@
         return mParams;
     }
 
-    /**
-     * Describe the kinds of special objects contained in this Parcelable's
-     * marshalled representation.
-     */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * Flatten this object in to a Parcel.
-     *
-     * @param dest The Parcel in which the object should be written.
-     * @param flags Additional flags about how the object should be written.
-     *        May be 0 or {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE}.
-     */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mSource);
-        dest.writeInt(mDestination);
-        dest.writeInt(mOpcode);
-        dest.writeInt(mParams.length);
-        dest.writeByteArray(mParams);
-    }
-
-    public static final Parcelable.Creator<HdmiCecMessage> CREATOR
-            = new Parcelable.Creator<HdmiCecMessage>() {
-        /**
-         * Rebuild a HdmiCecMessage previously stored with writeToParcel().
-         * @param p HdmiCecMessage object to read the Rating from
-         * @return a new HdmiCecMessage created from the data in the parcel
-         */
-        @Override
-        public HdmiCecMessage createFromParcel(Parcel p) {
-            int source = p.readInt();
-            int destination = p.readInt();
-            int opcode = p.readInt();
-            byte[] params = new byte[p.readInt()];
-            p.readByteArray(params);
-            return new HdmiCecMessage(source, destination, opcode, params);
-        }
-        @Override
-        public HdmiCecMessage[] newArray(int size) {
-            return new HdmiCecMessage[size];
-        }
-    };
-
     @Override
     public String toString() {
         StringBuffer s = new StringBuffer();
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
index d491ac2..4c88ce0 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
@@ -16,7 +16,7 @@
 
 package com.android.server.hdmi;
 
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.util.Slog;
 import android.util.SparseArray;
 
@@ -250,6 +250,9 @@
             return true;
         }
         int path = HdmiUtils.twoBytesToInt(params, offset);
+        if (path != Constants.INVALID_PHYSICAL_ADDRESS && path == mService.getPhysicalAddress()) {
+            return true;
+        }
         int portId = mService.pathToPortId(path);
         if (portId == Constants.INVALID_PORT_ID) {
             return false;
@@ -258,18 +261,19 @@
     }
 
     /**
-     * Check if the given type is valid. A valid type is one of the actual
-     * logical device types defined in the standard ({@link #DEVICE_TV},
-     * {@link #DEVICE_PLAYBACK}, {@link #DEVICE_TUNER}, {@link #DEVICE_RECORDER},
-     * and {@link #DEVICE_AUDIO_SYSTEM}).
+     * Check if the given type is valid. A valid type is one of the actual logical device types
+     * defined in the standard ({@link HdmiDeviceInfo#DEVICE_TV},
+     * {@link HdmiDeviceInfo#DEVICE_PLAYBACK}, {@link HdmiDeviceInfo#DEVICE_TUNER},
+     * {@link HdmiDeviceInfo#DEVICE_RECORDER}, and
+     * {@link HdmiDeviceInfo#DEVICE_AUDIO_SYSTEM}).
      *
      * @param type device type
      * @return true if the given type is valid
      */
     static boolean isValidType(int type) {
-        return (HdmiCecDeviceInfo.DEVICE_TV <= type
-                && type <= HdmiCecDeviceInfo.DEVICE_VIDEO_PROCESSOR)
-                && type != HdmiCecDeviceInfo.DEVICE_RESERVED;
+        return (HdmiDeviceInfo.DEVICE_TV <= type
+                && type <= HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR)
+                && type != HdmiDeviceInfo.DEVICE_RESERVED;
     }
 
     private class PhysicalAddressValidator implements ParameterValidator {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecStandbyModeHandler.java b/services/core/java/com/android/server/hdmi/HdmiCecStandbyModeHandler.java
new file mode 100644
index 0000000..8c40424
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/HdmiCecStandbyModeHandler.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import android.util.SparseArray;
+
+/**
+ * This class handles the incoming messages when HdmiCecService is in the standby mode.
+ */
+public final class HdmiCecStandbyModeHandler {
+
+    private interface CecMessageHandler {
+        boolean handle(HdmiCecMessage message);
+    }
+
+    private static final class Bystander implements CecMessageHandler {
+        @Override
+        public boolean handle(HdmiCecMessage message) {
+            return true;
+        }
+    }
+
+    private static final class Bypasser implements CecMessageHandler {
+        @Override
+        public boolean handle(HdmiCecMessage message) {
+            return false;
+        }
+    }
+
+    private final class Aborter implements CecMessageHandler {
+        private final int mReason;
+        public Aborter(int reason) {
+            mReason = reason;
+        }
+        @Override
+        public boolean handle(HdmiCecMessage message) {
+            mService.maySendFeatureAbortCommand(message, mReason);
+            return true;
+        }
+    }
+
+    private final class AutoOnHandler implements CecMessageHandler {
+        @Override
+        public boolean handle(HdmiCecMessage message) {
+            if (!mTv.getAutoWakeup()) {
+                mAborterRefused.handle(message);
+                return true;
+            }
+            return false;
+        }
+    }
+
+    private final class UserControlProcessedHandler implements CecMessageHandler {
+        @Override
+        public boolean handle(HdmiCecMessage message) {
+            // The power status here is always standby.
+            if (HdmiCecLocalDevice.isPowerOnOrToggleCommand(message)) {
+                return false;
+            } else if (HdmiCecLocalDevice.isPowerOffOrToggleCommand(message)) {
+                return true;
+            }
+            return mAborterIncorrectMode.handle(message);
+        }
+    }
+
+    private final HdmiControlService mService;
+    private final HdmiCecLocalDeviceTv mTv;
+
+    private final SparseArray<CecMessageHandler> mCecMessageHandlers = new SparseArray<>();
+    private final CecMessageHandler mDefaultHandler = new Aborter(
+            Constants.ABORT_UNRECOGNIZED_OPCODE);
+    private final CecMessageHandler mAborterIncorrectMode = new Aborter(
+            Constants.ABORT_NOT_IN_CORRECT_MODE);
+    private final CecMessageHandler mAborterRefused = new Aborter(Constants.ABORT_REFUSED);
+    private final CecMessageHandler mAutoOnHandler = new AutoOnHandler();
+    private final CecMessageHandler mBypasser = new Bypasser();
+    private final CecMessageHandler mBystander = new Bystander();
+    private final UserControlProcessedHandler
+            mUserControlProcessedHandler = new UserControlProcessedHandler();
+
+    public HdmiCecStandbyModeHandler(HdmiControlService service, HdmiCecLocalDeviceTv tv) {
+        mService = service;
+        mTv = tv;
+
+        addHandler(Constants.MESSAGE_IMAGE_VIEW_ON, mAutoOnHandler);
+        addHandler(Constants.MESSAGE_TEXT_VIEW_ON, mAutoOnHandler);
+
+        addHandler(Constants.MESSAGE_ACTIVE_SOURCE, mBystander);
+        addHandler(Constants.MESSAGE_REQUEST_ACTIVE_SOURCE, mBystander);
+        addHandler(Constants.MESSAGE_ROUTING_CHANGE, mBystander);
+        addHandler(Constants.MESSAGE_ROUTING_INFORMATION, mBystander);
+        addHandler(Constants.MESSAGE_SET_STREAM_PATH, mBystander);
+        addHandler(Constants.MESSAGE_STANDBY, mBystander);
+        addHandler(Constants.MESSAGE_SET_MENU_LANGUAGE, mBystander);
+        addHandler(Constants.MESSAGE_DEVICE_VENDOR_ID, mBystander);
+        addHandler(Constants.MESSAGE_USER_CONTROL_RELEASED, mBystander);
+        addHandler(Constants.MESSAGE_REPORT_POWER_STATUS, mBystander);
+        addHandler(Constants.MESSAGE_FEATURE_ABORT, mBystander);
+        addHandler(Constants.MESSAGE_INACTIVE_SOURCE, mBystander);
+        addHandler(Constants.MESSAGE_SYSTEM_AUDIO_MODE_STATUS, mBystander);
+        addHandler(Constants.MESSAGE_REPORT_AUDIO_STATUS, mBystander);
+
+        // If TV supports the following messages during power-on, ignore them and do nothing,
+        // else reply with <Feature Abort>["Unrecognized Opcode"]
+        // <Deck Status>, <Tuner Device Status>, <Tuner Cleared Status>, <Timer Status>
+        addHandler(Constants.MESSAGE_RECORD_STATUS, mBystander);
+
+        // If TV supports the following messages during power-on, reply with <Feature Abort>["Not
+        // in correct mode to respond"], else reply with <Feature Abort>["Unrecognized Opcode"]
+        // <Give Tuner Device Status>, <Select Digital Service>, <Tuner Step Decrement>,
+        // <Tuner Stem Increment>, <Menu Status>.
+        addHandler(Constants.MESSAGE_RECORD_TV_SCREEN, mAborterIncorrectMode);
+        addHandler(Constants.MESSAGE_INITIATE_ARC, mAborterIncorrectMode);
+        addHandler(Constants.MESSAGE_TERMINATE_ARC, mAborterIncorrectMode);
+
+        addHandler(Constants.MESSAGE_GIVE_PHYSICAL_ADDRESS, mBypasser);
+        addHandler(Constants.MESSAGE_GET_MENU_LANGUAGE, mBypasser);
+        addHandler(Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS, mBypasser);
+        addHandler(Constants.MESSAGE_GIVE_DEVICE_VENDOR_ID, mBypasser);
+        addHandler(Constants.MESSAGE_GIVE_OSD_NAME, mBypasser);
+        addHandler(Constants.MESSAGE_SET_OSD_NAME, mBypasser);
+
+        addHandler(Constants.MESSAGE_USER_CONTROL_PRESSED, mUserControlProcessedHandler);
+
+        addHandler(Constants.MESSAGE_GIVE_DEVICE_POWER_STATUS, mBypasser);
+        addHandler(Constants.MESSAGE_ABORT, mBypasser);
+        addHandler(Constants.MESSAGE_GET_CEC_VERSION, mBypasser);
+
+        addHandler(Constants.MESSAGE_VENDOR_COMMAND_WITH_ID, mAborterIncorrectMode);
+        addHandler(Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE, mAborterIncorrectMode);
+    }
+
+    private void addHandler(int opcode, CecMessageHandler handler) {
+        mCecMessageHandlers.put(opcode, handler);
+    }
+
+    /**
+     * Handles the CEC message in the standby mode.
+     *
+     * @param message {@link HdmiCecMessage} to be processed
+     * @return true if the message is handled in the handler, false means that the message is need
+     *         to be dispatched to the local device.
+     */
+    boolean handleCommand(HdmiCecMessage message) {
+        CecMessageHandler handler = mCecMessageHandlers.get(message.getOpcode());
+        if (handler != null) {
+            return handler.handle(message);
+        }
+        return mDefaultHandler.handle(message);
+    }
+}
diff --git a/services/core/java/com/android/server/hdmi/HdmiConfig.java b/services/core/java/com/android/server/hdmi/HdmiConfig.java
index 0793107..046f393 100644
--- a/services/core/java/com/android/server/hdmi/HdmiConfig.java
+++ b/services/core/java/com/android/server/hdmi/HdmiConfig.java
@@ -34,7 +34,7 @@
     static final int DEVICE_POLLING_RETRY = 1;
 
     // Number of retries for polling each device in periodic check (hotplug detection).
-    static final int HOTPLUG_DETECTION_RETRY = 2;
+    static final int HOTPLUG_DETECTION_RETRY = 1;
 
     // Number of retries for polling each device in address allocation mechanism.
     static final int ADDRESS_ALLOCATION_RETRY = 3;
@@ -46,5 +46,11 @@
     // action. They will have their own retransmission count.
     static final int RETRANSMISSION_COUNT = 1;
 
+    // Do not export the CEC devices connected to a legacy HDMI switch. The usage of legacy
+    // (non-CEC) switches is deprecated. They stop the correct operation of many mandatory
+    // CEC features. If set to true, do not pass the list of CEC devices behind the legacy
+    // switch since they won't be under control from TV.
+    static final boolean HIDE_DEVICES_BEHIND_LEGACY_SWITCH = true;
+
     private HdmiConfig() { /* cannot be instantiated */ }
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 87c90c6..cccc44c 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -22,7 +22,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiHotplugEvent;
 import android.hardware.hdmi.HdmiPortInfo;
@@ -73,6 +73,12 @@
 
     static final String PERMISSION = "android.permission.HDMI_CEC";
 
+    // The reason code to initiate intializeCec().
+    static final int INITIATED_BY_ENABLE_CEC = 0;
+    static final int INITIATED_BY_BOOT_UP = 1;
+    static final int INITIATED_BY_SCREEN_ON = 2;
+    static final int INITIATED_BY_WAKE_UP_MESSAGE = 3;
+
     /**
      * Interface to report send result.
      */
@@ -201,10 +207,10 @@
     private List<HdmiPortInfo> mPortInfo;
 
     // Map from path(physical address) to port ID.
-    private final SparseIntArray mPortIdMap = new SparseIntArray();
+    private UnmodifiableSparseIntArray mPortIdMap;
 
     // Map from port ID to HdmiPortInfo.
-    private final SparseArray<HdmiPortInfo> mPortInfoMap = new SparseArray<>();
+    private UnmodifiableSparseArray<HdmiPortInfo> mPortInfoMap;
 
     private HdmiCecMessageValidator mMessageValidator;
 
@@ -216,6 +222,9 @@
     @ServiceThreadOnly
     private boolean mStandbyMessageReceived = false;
 
+    @ServiceThreadOnly
+    private boolean mWakeUpMessageReceived = false;
+
     public HdmiControlService(Context context) {
         super(context);
         mLocalDevices = HdmiUtils.asImmutableList(getContext().getResources().getIntArray(
@@ -237,7 +246,7 @@
 
             // TODO: load value for mHdmiControlEnabled from preference.
             if (mHdmiControlEnabled) {
-                initializeCec(true);
+                initializeCec(INITIATED_BY_BOOT_UP);
             }
         } else {
             Slog.i(TAG, "Device does not support HDMI-CEC.");
@@ -260,6 +269,21 @@
         }
     }
 
+    /**
+     * Called when the initialization of local devices is complete.
+     */
+    private void onInitializeCecComplete() {
+        if (mPowerStatus == HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON) {
+            mPowerStatus = HdmiControlManager.POWER_STATUS_ON;
+        }
+        mWakeUpMessageReceived = false;
+
+        if (isTvDevice()) {
+            mCecController.setOption(HdmiTvClient.OPTION_CEC_AUTO_WAKEUP,
+                    tv().getAutoWakeup() ? HdmiTvClient.ENABLED : HdmiTvClient.DISABLED);
+        }
+    }
+
     boolean readBooleanSetting(String key, boolean defVal) {
         ContentResolver cr = getContext().getContentResolver();
         return Global.getInt(cr, key, defVal ? Constants.TRUE : Constants.FALSE) == Constants.TRUE;
@@ -270,18 +294,18 @@
         Global.putInt(cr, key, value ? Constants.TRUE : Constants.FALSE);
     }
 
-    private void initializeCec(boolean fromBootup) {
+    private void initializeCec(int initiatedBy) {
         mCecController.setOption(HdmiTvClient.OPTION_CEC_SERVICE_CONTROL,
                 HdmiTvClient.ENABLED);
-        initializeLocalDevices(mLocalDevices, fromBootup);
+        initializeLocalDevices(mLocalDevices, initiatedBy);
     }
 
     @ServiceThreadOnly
-    private void initializeLocalDevices(final List<Integer> deviceTypes, final boolean fromBootup) {
+    private void initializeLocalDevices(final List<Integer> deviceTypes, final int initiatedBy) {
         assertRunOnServiceThread();
         // A container for [Logical Address, Local device info].
         final SparseArray<HdmiCecLocalDevice> devices = new SparseArray<>();
-        final SparseIntArray finished = new SparseIntArray();
+        final int[] finished = new int[1];
         clearLocalDevices();
         for (int type : deviceTypes) {
             final HdmiCecLocalDevice localDevice = HdmiCecLocalDevice.create(this, type);
@@ -293,20 +317,17 @@
                     if (logicalAddress == Constants.ADDR_UNREGISTERED) {
                         Slog.e(TAG, "Failed to allocate address:[device_type:" + deviceType + "]");
                     } else {
-                        HdmiCecDeviceInfo deviceInfo = createDeviceInfo(logicalAddress, deviceType);
+                        HdmiDeviceInfo deviceInfo = createDeviceInfo(logicalAddress, deviceType);
                         localDevice.setDeviceInfo(deviceInfo);
                         mCecController.addLocalDevice(deviceType, localDevice);
                         mCecController.addLogicalAddress(logicalAddress);
                         devices.append(logicalAddress, localDevice);
                     }
-                    finished.append(deviceType, logicalAddress);
 
                     // Address allocation completed for all devices. Notify each device.
-                    if (deviceTypes.size() == finished.size()) {
-                        if (mPowerStatus == HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON) {
-                            mPowerStatus = HdmiControlManager.POWER_STATUS_ON;
-                        }
-                        notifyAddressAllocated(devices, fromBootup);
+                    if (deviceTypes.size() == ++finished[0]) {
+                        onInitializeCecComplete();
+                        notifyAddressAllocated(devices, initiatedBy);
                     }
                 }
             });
@@ -314,13 +335,12 @@
     }
 
     @ServiceThreadOnly
-    private void notifyAddressAllocated(SparseArray<HdmiCecLocalDevice> devices,
-            boolean fromBootup) {
+    private void notifyAddressAllocated(SparseArray<HdmiCecLocalDevice> devices, int initiatedBy) {
         assertRunOnServiceThread();
         for (int i = 0; i < devices.size(); ++i) {
             int address = devices.keyAt(i);
             HdmiCecLocalDevice device = devices.valueAt(i);
-            device.handleAddressAllocated(address, fromBootup);
+            device.handleAddressAllocated(address, initiatedBy);
         }
     }
 
@@ -340,10 +360,14 @@
             return;
         }
 
+        SparseArray<HdmiPortInfo> portInfoMap = new SparseArray<>();
+        SparseIntArray portIdMap = new SparseIntArray();
         for (HdmiPortInfo info : cecPortInfo) {
-            mPortIdMap.put(info.getAddress(), info.getId());
-            mPortInfoMap.put(info.getId(), info);
+            portIdMap.put(info.getAddress(), info.getId());
+            portInfoMap.put(info.getId(), info);
         }
+        mPortIdMap = new UnmodifiableSparseIntArray(portIdMap);
+        mPortInfoMap = new UnmodifiableSparseArray<>(portInfoMap);
 
         if (mMhlController == null) {
             mPortInfo = Collections.unmodifiableList(Arrays.asList(cecPortInfo));
@@ -377,9 +401,7 @@
      * @param portId HDMI port id
      * @return {@link HdmiPortInfo} for the given port
      */
-    @ServiceThreadOnly
     HdmiPortInfo getPortInfo(int portId) {
-        assertRunOnServiceThread();
         return mPortInfoMap.get(portId, null);
     }
 
@@ -387,9 +409,7 @@
      * Returns the routing path (physical address) of the HDMI port for the given
      * port id.
      */
-    @ServiceThreadOnly
     int portIdToPath(int portId) {
-        assertRunOnServiceThread();
         HdmiPortInfo portInfo = getPortInfo(portId);
         if (portInfo == null) {
             Slog.e(TAG, "Cannot find the port info: " + portId);
@@ -404,16 +424,12 @@
      * the port id to be returned is the ID associated with the port address
      * 0x1000 (1.0.0.0) which is the topmost path of the given routing path.
      */
-    @ServiceThreadOnly
     int pathToPortId(int path) {
-        assertRunOnServiceThread();
         int portAddress = path & Constants.ROUTING_PATH_TOP_MASK;
         return mPortIdMap.get(portAddress, Constants.INVALID_PORT_ID);
     }
 
-    @ServiceThreadOnly
     boolean isValidPortId(int portId) {
-        assertRunOnServiceThread();
         return getPortInfo(portId) != null;
     }
 
@@ -451,7 +467,7 @@
     }
 
     @ServiceThreadOnly
-    HdmiCecDeviceInfo getDeviceInfo(int logicalAddress) {
+    HdmiDeviceInfo getDeviceInfo(int logicalAddress) {
         assertRunOnServiceThread();
         HdmiCecLocalDeviceTv tv = tv();
         if (tv == null) {
@@ -470,9 +486,7 @@
     /**
      * Whether a device of the specified physical address is connected to ARC enabled port.
      */
-    @ServiceThreadOnly
     boolean isConnectedToArcPort(int physicalAddress) {
-        assertRunOnServiceThread();
         int portId = mPortIdMap.get(physicalAddress);
         if (portId != Constants.INVALID_PORT_ID) {
             return mPortInfoMap.get(portId).isArcSupported();
@@ -503,13 +517,32 @@
     @ServiceThreadOnly
     void sendCecCommand(HdmiCecMessage command, @Nullable SendMessageCallback callback) {
         assertRunOnServiceThread();
-        mCecController.sendCommand(command, callback);
+        if (mMessageValidator.isValid(command)) {
+            mCecController.sendCommand(command, callback);
+        } else {
+            Slog.e(TAG, "Invalid message type:" + command);
+            if (callback != null) {
+                callback.onSendCompleted(Constants.SEND_RESULT_FAILURE);
+            }
+        }
     }
 
     @ServiceThreadOnly
     void sendCecCommand(HdmiCecMessage command) {
         assertRunOnServiceThread();
-        mCecController.sendCommand(command, null);
+        sendCecCommand(command, null);
+    }
+
+    /**
+     * Send <Feature Abort> command on the given CEC message if possible.
+     * If the aborted message is invalid, then it wont send the message.
+     * @param command original command to be aborted
+     * @param reason reason of feature abort
+     */
+    @ServiceThreadOnly
+    void maySendFeatureAbortCommand(HdmiCecMessage command, int reason) {
+        assertRunOnServiceThread();
+        mCecController.maySendFeatureAbortCommand(command, reason);
     }
 
     @ServiceThreadOnly
@@ -620,10 +653,10 @@
         }
     }
 
-    private HdmiCecDeviceInfo createDeviceInfo(int logicalAddress, int deviceType) {
+    private HdmiDeviceInfo createDeviceInfo(int logicalAddress, int deviceType) {
         // TODO: find better name instead of model name.
         String displayName = Build.MODEL;
-        return new HdmiCecDeviceInfo(logicalAddress,
+        return new HdmiDeviceInfo(logicalAddress,
                 getPhysicalAddress(), pathToPortId(getPhysicalAddress()), deviceType,
                 getVendorId(), displayName);
     }
@@ -721,7 +754,7 @@
         }
 
         @Override
-        public HdmiCecDeviceInfo getActiveSource() {
+        public HdmiDeviceInfo getActiveSource() {
             HdmiCecLocalDeviceTv tv = tv();
             if (tv == null) {
                 Slog.w(TAG, "Local tv device not available");
@@ -729,13 +762,13 @@
             }
             ActiveSource activeSource = tv.getActiveSource();
             if (activeSource.isValid()) {
-                return new HdmiCecDeviceInfo(activeSource.logicalAddress,
-                        activeSource.physicalAddress, HdmiCecDeviceInfo.PORT_INVALID,
-                        HdmiCecDeviceInfo.DEVICE_INACTIVE, 0, "");
+                return new HdmiDeviceInfo(activeSource.logicalAddress,
+                        activeSource.physicalAddress, HdmiDeviceInfo.PORT_INVALID,
+                        HdmiDeviceInfo.DEVICE_INACTIVE, 0, "");
             }
             int activePath = tv.getActivePath();
-            if (activePath != HdmiCecDeviceInfo.PATH_INVALID) {
-                return new HdmiCecDeviceInfo(activePath, tv.getActivePortId());
+            if (activePath != HdmiDeviceInfo.PATH_INVALID) {
+                return new HdmiDeviceInfo(activePath, tv.getActivePortId());
             }
             return null;
         }
@@ -917,7 +950,7 @@
         }
 
         @Override
-        public List<HdmiCecDeviceInfo> getInputDevices() {
+        public List<HdmiDeviceInfo> getInputDevices() {
             enforceAccessPermission();
             // No need to hold the lock for obtaining TV device as the local device instance
             // is preserved while the HDMI control is enabled.
@@ -996,6 +1029,7 @@
             }
             switch (key) {
                 case HdmiTvClient.OPTION_CEC_AUTO_WAKEUP:
+                    tv().setAutoWakeup(value == HdmiTvClient.ENABLED);
                     mCecController.setOption(key, value);
                     break;
                 case HdmiTvClient.OPTION_CEC_AUTO_DEVICE_OFF:
@@ -1185,7 +1219,7 @@
         }
     }
 
-    void invokeDeviceEventListeners(HdmiCecDeviceInfo device, boolean activated) {
+    void invokeDeviceEventListeners(HdmiDeviceInfo device, boolean activated) {
         synchronized (mLock) {
             for (IHdmiDeviceEventListener listener : mDeviceEventListeners) {
                 try {
@@ -1248,7 +1282,7 @@
         }
     }
 
-    void invokeInputChangeListener(HdmiCecDeviceInfo info) {
+    void invokeInputChangeListener(HdmiDeviceInfo info) {
         synchronized (mLock) {
             if (mInputChangeListener != null) {
                 try {
@@ -1303,7 +1337,19 @@
                 try {
                     mRecordListener.onTimerRecordingResult(result);
                 } catch (RemoteException e) {
-                    Slog.w(TAG, "Failed to call onOneTouchRecordResult.", e);
+                    Slog.w(TAG, "Failed to call onTimerRecordingResult.", e);
+                }
+            }
+        }
+    }
+
+    void invokeClearTimerRecordingResult(int result) {
+        synchronized (mLock) {
+            if (mRecordListener != null) {
+                try {
+                    mRecordListener.onClearTimerRecordingResult(result);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Failed to call onClearTimerRecordingResult.", e);
                 }
             }
         }
@@ -1344,13 +1390,8 @@
         }
     }
 
-    private static boolean hasSameTopPort(int path1, int path2) {
-        return (path1 & Constants.ROUTING_PATH_TOP_MASK)
-                == (path2 & Constants.ROUTING_PATH_TOP_MASK);
-    }
-
     private HdmiCecLocalDeviceTv tv() {
-        return (HdmiCecLocalDeviceTv) mCecController.getLocalDevice(HdmiCecDeviceInfo.DEVICE_TV);
+        return (HdmiCecLocalDeviceTv) mCecController.getLocalDevice(HdmiDeviceInfo.DEVICE_TV);
     }
 
     boolean isTvDevice() {
@@ -1359,7 +1400,7 @@
 
     private HdmiCecLocalDevicePlayback playback() {
         return (HdmiCecLocalDevicePlayback)
-                mCecController.getLocalDevice(HdmiCecDeviceInfo.DEVICE_PLAYBACK);
+                mCecController.getLocalDevice(HdmiDeviceInfo.DEVICE_PLAYBACK);
     }
 
     AudioManager getAudioManager() {
@@ -1393,6 +1434,7 @@
     @ServiceThreadOnly
     void wakeUp() {
         assertRunOnServiceThread();
+        mWakeUpMessageReceived = true;
         PowerManager pm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE);
         pm.wakeUp(SystemClock.uptimeMillis());
         // PowerManger will send the broadcast Intent.ACTION_SCREEN_ON and after this gets
@@ -1409,13 +1451,22 @@
         // the intent, the sequence will continue at onStandby().
     }
 
+    void nap() {
+        PowerManager pm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE);
+        pm.nap(SystemClock.uptimeMillis());
+    }
+
     @ServiceThreadOnly
     private void onWakeUp() {
         assertRunOnServiceThread();
         mPowerStatus = HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON;
         if (mCecController != null) {
             if (mHdmiControlEnabled) {
-                initializeCec(true);
+                int startReason = INITIATED_BY_SCREEN_ON;
+                if (mWakeUpMessageReceived) {
+                    startReason = INITIATED_BY_WAKE_UP_MESSAGE;
+                }
+                initializeCec(startReason);
             }
         } else {
             Slog.i(TAG, "Device does not support HDMI-CEC.");
@@ -1532,7 +1583,7 @@
         }
 
         if (enabled) {
-            initializeCec(false);
+            initializeCec(INITIATED_BY_ENABLE_CEC);
         } else {
             disableDevices(new PendingActionClearedCallback() {
                 @Override
diff --git a/services/core/java/com/android/server/hdmi/HdmiUtils.java b/services/core/java/com/android/server/hdmi/HdmiUtils.java
index b92e823..a52e0d2 100644
--- a/services/core/java/com/android/server/hdmi/HdmiUtils.java
+++ b/services/core/java/com/android/server/hdmi/HdmiUtils.java
@@ -16,7 +16,7 @@
 
 package com.android.server.hdmi;
 
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.util.Slog;
 import android.util.SparseArray;
 
@@ -30,21 +30,21 @@
 final class HdmiUtils {
 
     private static final int[] ADDRESS_TO_TYPE = {
-        HdmiCecDeviceInfo.DEVICE_TV,  // ADDR_TV
-        HdmiCecDeviceInfo.DEVICE_RECORDER,  // ADDR_RECORDER_1
-        HdmiCecDeviceInfo.DEVICE_RECORDER,  // ADDR_RECORDER_2
-        HdmiCecDeviceInfo.DEVICE_TUNER,  // ADDR_TUNER_1
-        HdmiCecDeviceInfo.DEVICE_PLAYBACK,  // ADDR_PLAYBACK_1
-        HdmiCecDeviceInfo.DEVICE_AUDIO_SYSTEM,  // ADDR_AUDIO_SYSTEM
-        HdmiCecDeviceInfo.DEVICE_TUNER,  // ADDR_TUNER_2
-        HdmiCecDeviceInfo.DEVICE_TUNER,  // ADDR_TUNER_3
-        HdmiCecDeviceInfo.DEVICE_PLAYBACK,  // ADDR_PLAYBACK_2
-        HdmiCecDeviceInfo.DEVICE_RECORDER,  // ADDR_RECORDER_3
-        HdmiCecDeviceInfo.DEVICE_TUNER,  // ADDR_TUNER_4
-        HdmiCecDeviceInfo.DEVICE_PLAYBACK,  // ADDR_PLAYBACK_3
-        HdmiCecDeviceInfo.DEVICE_RESERVED,
-        HdmiCecDeviceInfo.DEVICE_RESERVED,
-        HdmiCecDeviceInfo.DEVICE_TV,  // ADDR_SPECIFIC_USE
+        HdmiDeviceInfo.DEVICE_TV,  // ADDR_TV
+        HdmiDeviceInfo.DEVICE_RECORDER,  // ADDR_RECORDER_1
+        HdmiDeviceInfo.DEVICE_RECORDER,  // ADDR_RECORDER_2
+        HdmiDeviceInfo.DEVICE_TUNER,  // ADDR_TUNER_1
+        HdmiDeviceInfo.DEVICE_PLAYBACK,  // ADDR_PLAYBACK_1
+        HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM,  // ADDR_AUDIO_SYSTEM
+        HdmiDeviceInfo.DEVICE_TUNER,  // ADDR_TUNER_2
+        HdmiDeviceInfo.DEVICE_TUNER,  // ADDR_TUNER_3
+        HdmiDeviceInfo.DEVICE_PLAYBACK,  // ADDR_PLAYBACK_2
+        HdmiDeviceInfo.DEVICE_RECORDER,  // ADDR_RECORDER_3
+        HdmiDeviceInfo.DEVICE_TUNER,  // ADDR_TUNER_4
+        HdmiDeviceInfo.DEVICE_PLAYBACK,  // ADDR_PLAYBACK_3
+        HdmiDeviceInfo.DEVICE_RESERVED,
+        HdmiDeviceInfo.DEVICE_RESERVED,
+        HdmiDeviceInfo.DEVICE_TV,  // ADDR_SPECIFIC_USE
     };
 
     private static final String[] DEFAULT_NAMES = {
@@ -90,7 +90,7 @@
         if (isValidAddress(address)) {
             return ADDRESS_TO_TYPE[address];
         }
-        return HdmiCecDeviceInfo.DEVICE_INACTIVE;
+        return HdmiDeviceInfo.DEVICE_INACTIVE;
     }
 
     /**
diff --git a/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
index 813901d..51e68b6 100644
--- a/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
+++ b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
@@ -16,7 +16,7 @@
 
 package com.android.server.hdmi;
 
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.util.Slog;
 
 import com.android.server.hdmi.HdmiControlService.DevicePollingCallback;
@@ -33,7 +33,7 @@
  * For other devices, keep 15 secs period.
  */
 // Seq #3
-final class HotplugDetectionAction extends FeatureAction {
+final class HotplugDetectionAction extends HdmiCecFeatureAction {
     private static final String TAG = "HotPlugDetectionAction";
 
     private static final int POLLING_INTERVAL_MS = 5000;
@@ -161,11 +161,11 @@
         }
     }
 
-    private static BitSet infoListToBitSet(List<HdmiCecDeviceInfo> infoList, boolean audioOnly) {
+    private static BitSet infoListToBitSet(List<HdmiDeviceInfo> infoList, boolean audioOnly) {
         BitSet set = new BitSet(NUM_OF_ADDRESS);
-        for (HdmiCecDeviceInfo info : infoList) {
+        for (HdmiDeviceInfo info : infoList) {
             if (audioOnly) {
-                if (info.getDeviceType() == HdmiCecDeviceInfo.DEVICE_AUDIO_SYSTEM) {
+                if (info.getDeviceType() == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) {
                     set.set(info.getLogicalAddress());
                 }
             } else {
@@ -207,7 +207,7 @@
     }
 
     private void mayChangeRoutingPath(int address) {
-        HdmiCecDeviceInfo info = tv().getDeviceInfo(address);
+        HdmiDeviceInfo info = tv().getDeviceInfo(address);
         if (info != null) {
             tv().handleRemoveActiveRoutingPath(info.getPhysicalAddress());
         }
@@ -236,7 +236,7 @@
     }
 
     private void mayDisableSystemAudioAndARC(int address) {
-        if (HdmiUtils.getTypeFromAddress(address) != HdmiCecDeviceInfo.DEVICE_AUDIO_SYSTEM) {
+        if (HdmiUtils.getTypeFromAddress(address) != HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) {
             return;
         }
 
diff --git a/services/core/java/com/android/server/hdmi/NewDeviceAction.java b/services/core/java/com/android/server/hdmi/NewDeviceAction.java
index 907015b..a5fdbea 100644
--- a/services/core/java/com/android/server/hdmi/NewDeviceAction.java
+++ b/services/core/java/com/android/server/hdmi/NewDeviceAction.java
@@ -15,7 +15,7 @@
  */
 package com.android.server.hdmi;
 
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.util.Slog;
 
 import com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource;
@@ -28,12 +28,12 @@
  * connected HDMI-CEC device broadcasts to announce its advent. Additional commands are issued in
  * this action to gather more information on the device such as OSD name and device vendor ID.
  *
- * <p>The result is made in the form of {@link HdmiCecDeviceInfo} object, and passed to service
+ * <p>The result is made in the form of {@link HdmiDeviceInfo} object, and passed to service
  * for the management through its life cycle.
  *
  * <p>Package-private, accessed by {@link HdmiControlService} only.
  */
-final class NewDeviceAction extends FeatureAction {
+final class NewDeviceAction extends HdmiCecFeatureAction {
 
     private static final String TAG = "NewDeviceAction";
 
@@ -152,14 +152,14 @@
         if (mDisplayName == null) {
             mDisplayName = HdmiUtils.getDefaultDeviceName(mDeviceLogicalAddress);
         }
-        tv().addCecDevice(new HdmiCecDeviceInfo(
+        tv().addCecDevice(new HdmiDeviceInfo(
                 mDeviceLogicalAddress, mDevicePhysicalAddress,
                 tv().getPortId(mDevicePhysicalAddress),
                 HdmiUtils.getTypeFromAddress(mDeviceLogicalAddress),
                 mVendorId, mDisplayName));
 
         if (HdmiUtils.getTypeFromAddress(mDeviceLogicalAddress)
-                == HdmiCecDeviceInfo.DEVICE_AUDIO_SYSTEM) {
+                == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) {
             if (tv().getSystemAudioModeSetting()) {
                 addAndStartAction(new SystemAudioAutoInitiationAction(localDevice(),
                         mDeviceLogicalAddress));
diff --git a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
index 6299b99..7db991a 100644
--- a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
+++ b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
@@ -17,19 +17,18 @@
 
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.IHdmiControlCallback;
+import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback;
 import android.os.RemoteException;
 import android.util.Slog;
 
 /**
- * Feature action that performs one touch play against TV/Display device.
- *
- * This action is initiated via {@link HdmiControlManager#oneTouchPlay()} from
- * the Android system working as playback device to turn on the TV, and switch the input.
- *
- * <p>Package-private, accessed by {@link HdmiControlService} only.
+ * Feature action that performs one touch play against TV/Display device. This action is initiated
+ * via {@link android.hardware.hdmi.HdmiPlaybackClient#oneTouchPlay(OneTouchPlayCallback)} from the
+ * Android system working as playback device to turn on the TV, and switch the input.
+ * <p>
+ * Package-private, accessed by {@link HdmiControlService} only.
  */
-
-final class OneTouchPlayAction extends FeatureAction {
+final class OneTouchPlayAction extends HdmiCecFeatureAction {
     private static final String TAG = "OneTouchPlayAction";
 
     // State in which the action is waiting for <Report Power Status>. In normal situation
diff --git a/services/core/java/com/android/server/hdmi/OneTouchRecordAction.java b/services/core/java/com/android/server/hdmi/OneTouchRecordAction.java
index befc640..39c0d7f 100644
--- a/services/core/java/com/android/server/hdmi/OneTouchRecordAction.java
+++ b/services/core/java/com/android/server/hdmi/OneTouchRecordAction.java
@@ -29,7 +29,7 @@
 /**
  * Feature action that performs one touch record.
  */
-public class OneTouchRecordAction extends FeatureAction {
+public class OneTouchRecordAction extends HdmiCecFeatureAction {
     private static final String TAG = "OneTouchRecordAction";
 
     // Timer out for waiting <Record Status> 120s
diff --git a/services/core/java/com/android/server/hdmi/RequestArcAction.java b/services/core/java/com/android/server/hdmi/RequestArcAction.java
index cf44607..9c530a3 100644
--- a/services/core/java/com/android/server/hdmi/RequestArcAction.java
+++ b/services/core/java/com/android/server/hdmi/RequestArcAction.java
@@ -16,14 +16,14 @@
 
 package com.android.server.hdmi;
 
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 
 import android.util.Slog;
 
 /**
  * Base feature action class for &lt;Request ARC Initiation&gt;/&lt;Request ARC Termination&gt;.
  */
-abstract class RequestArcAction extends FeatureAction {
+abstract class RequestArcAction extends HdmiCecFeatureAction {
     private static final String TAG = "RequestArcAction";
 
     // State in which waits for ARC response.
@@ -42,8 +42,8 @@
      */
     RequestArcAction(HdmiCecLocalDevice source, int avrAddress) {
         super(source);
-        HdmiUtils.verifyAddressType(getSourceAddress(), HdmiCecDeviceInfo.DEVICE_TV);
-        HdmiUtils.verifyAddressType(avrAddress, HdmiCecDeviceInfo.DEVICE_AUDIO_SYSTEM);
+        HdmiUtils.verifyAddressType(getSourceAddress(), HdmiDeviceInfo.DEVICE_TV);
+        HdmiUtils.verifyAddressType(avrAddress, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
         mAvrAddress = avrAddress;
     }
 
diff --git a/services/core/java/com/android/server/hdmi/RoutingControlAction.java b/services/core/java/com/android/server/hdmi/RoutingControlAction.java
index f50ae9b..435ab7f 100644
--- a/services/core/java/com/android/server/hdmi/RoutingControlAction.java
+++ b/services/core/java/com/android/server/hdmi/RoutingControlAction.java
@@ -17,7 +17,7 @@
 package com.android.server.hdmi;
 
 import android.annotation.Nullable;
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.IHdmiControlCallback;
 import android.os.RemoteException;
@@ -38,7 +38,7 @@
  * <li> Routing at CEC enable time
  * </ul>
  */
-final class RoutingControlAction extends FeatureAction {
+final class RoutingControlAction extends HdmiCecFeatureAction {
     private static final String TAG = "RoutingControlAction";
 
     // State in which we wait for <Routing Information> to arrive. If timed out, we use the
@@ -155,7 +155,7 @@
         }
         switch (timeoutState) {
             case STATE_WAIT_FOR_ROUTING_INFORMATION:
-                HdmiCecDeviceInfo device = tv().getDeviceInfoByPath(mCurrentRoutingPath);
+                HdmiDeviceInfo device = tv().getDeviceInfoByPath(mCurrentRoutingPath);
                 if (device != null && mQueryDevicePowerStatus) {
                     int deviceLogicalAddress = device.getLogicalAddress();
                     queryDevicePowerStatus(deviceLogicalAddress, new SendMessageCallback() {
diff --git a/services/core/java/com/android/server/hdmi/SendKeyAction.java b/services/core/java/com/android/server/hdmi/SendKeyAction.java
index ca2826e..9f09eb4 100644
--- a/services/core/java/com/android/server/hdmi/SendKeyAction.java
+++ b/services/core/java/com/android/server/hdmi/SendKeyAction.java
@@ -32,7 +32,7 @@
  *
  * <p>Package-private, accessed by {@link HdmiControlService} only.
  */
-final class SendKeyAction extends FeatureAction {
+final class SendKeyAction extends HdmiCecFeatureAction {
     private static final String TAG = "SendKeyAction";
 
     // State in which the action is at work. The state is set in {@link #start()} and
diff --git a/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java b/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java
index e0c1ad5..9f7f98a 100644
--- a/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java
+++ b/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java
@@ -16,7 +16,7 @@
 
 package com.android.server.hdmi;
 
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.util.Slog;
 
 /**
@@ -24,7 +24,7 @@
  * Once TV gets &lt;Initiate ARC&gt;, TV sends &lt;Report ARC Initiated&gt; to AV Receiver.
  * If it fails or it gets &lt;Terminate ARC&gt;, TV just disables ARC.
  */
-final class SetArcTransmissionStateAction extends FeatureAction {
+final class SetArcTransmissionStateAction extends HdmiCecFeatureAction {
     private static final String TAG = "SetArcTransmissionStateAction";
 
     // State in which the action sent <Rerpot Arc Initiated> and
@@ -44,8 +44,8 @@
     SetArcTransmissionStateAction(HdmiCecLocalDevice source, int avrAddress,
             boolean enabled) {
         super(source);
-        HdmiUtils.verifyAddressType(getSourceAddress(), HdmiCecDeviceInfo.DEVICE_TV);
-        HdmiUtils.verifyAddressType(avrAddress, HdmiCecDeviceInfo.DEVICE_AUDIO_SYSTEM);
+        HdmiUtils.verifyAddressType(getSourceAddress(), HdmiDeviceInfo.DEVICE_TV);
+        HdmiUtils.verifyAddressType(avrAddress, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
         mAvrAddress = avrAddress;
         mEnabled = enabled;
     }
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioAction.java b/services/core/java/com/android/server/hdmi/SystemAudioAction.java
index 4be036a..7e45a99 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioAction.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioAction.java
@@ -17,7 +17,7 @@
 package com.android.server.hdmi;
 
 import android.annotation.Nullable;
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.IHdmiControlCallback;
 import android.os.RemoteException;
@@ -28,7 +28,7 @@
 /**
  * Base feature action class for SystemAudioActionFromTv and SystemAudioActionFromAvr.
  */
-abstract class SystemAudioAction extends FeatureAction {
+abstract class SystemAudioAction extends HdmiCecFeatureAction {
     private static final String TAG = "SystemAudioAction";
 
     // Transient state to differentiate with STATE_NONE where the on-finished callback
@@ -65,7 +65,7 @@
     SystemAudioAction(HdmiCecLocalDevice source, int avrAddress, boolean targetStatus,
             IHdmiControlCallback callback) {
         super(source);
-        HdmiUtils.verifyAddressType(avrAddress, HdmiCecDeviceInfo.DEVICE_AUDIO_SYSTEM);
+        HdmiUtils.verifyAddressType(avrAddress, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
         mAvrLogicalAddress = avrAddress;
         mTargetAudioStatus = targetStatus;
         mCallback = callback;
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioActionFromAvr.java b/services/core/java/com/android/server/hdmi/SystemAudioActionFromAvr.java
index df9bdfc..eb5119b 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioActionFromAvr.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioActionFromAvr.java
@@ -16,7 +16,7 @@
 
 package com.android.server.hdmi;
 
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.IHdmiControlCallback;
 
@@ -37,7 +37,7 @@
     SystemAudioActionFromAvr(HdmiCecLocalDevice source, int avrAddress,
             boolean targetStatus, IHdmiControlCallback callback) {
         super(source, avrAddress, targetStatus, callback);
-        HdmiUtils.verifyAddressType(getSourceAddress(), HdmiCecDeviceInfo.DEVICE_TV);
+        HdmiUtils.verifyAddressType(getSourceAddress(), HdmiDeviceInfo.DEVICE_TV);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioActionFromTv.java b/services/core/java/com/android/server/hdmi/SystemAudioActionFromTv.java
index cb3588c..02ecd13 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioActionFromTv.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioActionFromTv.java
@@ -16,7 +16,7 @@
 
 package com.android.server.hdmi;
 
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.IHdmiControlCallback;
 
 
@@ -37,7 +37,7 @@
     SystemAudioActionFromTv(HdmiCecLocalDevice sourceAddress, int avrAddress,
             boolean targetStatus, IHdmiControlCallback callback) {
         super(sourceAddress, avrAddress, targetStatus, callback);
-        HdmiUtils.verifyAddressType(getSourceAddress(), HdmiCecDeviceInfo.DEVICE_TV);
+        HdmiUtils.verifyAddressType(getSourceAddress(), HdmiDeviceInfo.DEVICE_TV);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
index 137cada..3653aac 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
@@ -22,7 +22,7 @@
  * Action to initiate system audio once AVR is detected on Device discovery action.
  */
 // Seq #27
-final class SystemAudioAutoInitiationAction extends FeatureAction {
+final class SystemAudioAutoInitiationAction extends HdmiCecFeatureAction {
     private final int mAvrAddress;
 
     // State that waits for <System Audio Mode Status> once send
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java b/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java
index 1066204..bfcda50 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java
@@ -27,7 +27,7 @@
 /**
  * Action to update audio status (volume or mute) of audio amplifier
  */
-final class SystemAudioStatusAction extends FeatureAction {
+final class SystemAudioStatusAction extends HdmiCecFeatureAction {
     private static final String TAG = "SystemAudioStatusAction";
 
     // State that waits for <ReportAudioStatus>.
diff --git a/services/core/java/com/android/server/hdmi/TimerRecordingAction.java b/services/core/java/com/android/server/hdmi/TimerRecordingAction.java
index 1dc26f1..8fc0182 100644
--- a/services/core/java/com/android/server/hdmi/TimerRecordingAction.java
+++ b/services/core/java/com/android/server/hdmi/TimerRecordingAction.java
@@ -16,10 +16,11 @@
 
 package com.android.server.hdmi;
 
+import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION;
+import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE;
 import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_ANALOGUE;
 import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_DIGITAL;
 import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_EXTERNAL;
-import static android.hardware.hdmi.HdmiControlManager.TIME_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION;
 
 import android.util.Slog;
 
@@ -30,7 +31,7 @@
 /**
  * Feature action that performs timer recording.
  */
-public class TimerRecordingAction extends FeatureAction {
+public class TimerRecordingAction extends HdmiCecFeatureAction {
     private static final String TAG = "TimerRecordingAction";
 
     // Timer out for waiting <Timer Status> 120s.
@@ -74,7 +75,7 @@
                 break;
             default:
                 tv().announceTimerRecordingResult(
-                        TIME_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
+                        TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE);
                 finish();
                 return;
         }
@@ -82,11 +83,13 @@
             @Override
             public void onSendCompleted(int error) {
                 if (error != Constants.SEND_RESULT_SUCCESS) {
-                    mState = STATE_WAITING_FOR_TIMER_STATUS;
-                    addTimer(mState, TIMER_STATUS_TIMEOUT_MS);
+                    tv().announceTimerRecordingResult(
+                            TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
                     finish();
                     return;
                 }
+                mState = STATE_WAITING_FOR_TIMER_STATUS;
+                addTimer(mState, TIMER_STATUS_TIMEOUT_MS);
             }
         });
     }
@@ -127,7 +130,7 @@
 
     private boolean handleFeatureAbort(HdmiCecMessage cmd) {
         byte[] params = cmd.getParams();
-        int messageType = params[0];
+        int messageType = params[0] & 0xFF;
         switch (messageType) {
             case Constants.MESSAGE_SET_DIGITAL_TIMER: // fall through
             case Constants.MESSAGE_SET_ANALOG_TIMER: // fall through
@@ -136,9 +139,9 @@
             default:
                 return false;
         }
-        int reason = params[1];
+        int reason = params[1] & 0xFF;
         Slog.i(TAG, "[Feature Abort] for " + messageType + " reason:" + reason);
-        tv().announceTimerRecordingResult(TIME_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
+        tv().announceTimerRecordingResult(TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
         finish();
         return true;
     }
@@ -163,7 +166,7 @@
             return;
         }
 
-        tv().announceTimerRecordingResult(TIME_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
+        tv().announceTimerRecordingResult(TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
         finish();
     }
 }
diff --git a/services/core/java/com/android/server/hdmi/UnmodifiableSparseArray.java b/services/core/java/com/android/server/hdmi/UnmodifiableSparseArray.java
new file mode 100644
index 0000000..7791797
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/UnmodifiableSparseArray.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import android.util.SparseArray;
+
+/**
+ * Unmodifiable version of {@link SparseArray}.
+ */
+final class UnmodifiableSparseArray<E> {
+    private static final String TAG = "ImmutableSparseArray";
+
+    private final SparseArray<E> mArray;
+
+    public UnmodifiableSparseArray(SparseArray<E> array) {
+       mArray = array;
+    }
+
+    public int size() {
+        return mArray.size();
+    }
+
+    public E get(int key) {
+        return mArray.get(key);
+    }
+
+    public E get(int key, E valueIfKeyNotFound) {
+        return mArray.get(key, valueIfKeyNotFound);
+    }
+
+    public int keyAt(int index) {
+        return mArray.keyAt(index);
+    }
+
+    public E valueAt(int index) {
+        return mArray.valueAt(index);
+    }
+
+    public int indexOfValue(E value) {
+        return mArray.indexOfValue(value);
+    }
+
+    @Override
+    public String toString() {
+        return mArray.toString();
+    }
+}
diff --git a/services/core/java/com/android/server/hdmi/UnmodifiableSparseIntArray.java b/services/core/java/com/android/server/hdmi/UnmodifiableSparseIntArray.java
new file mode 100644
index 0000000..cada855
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/UnmodifiableSparseIntArray.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import android.util.SparseIntArray;
+
+/**
+ * Unmodifiable version of {@link SparseIntArray}.
+ */
+final class UnmodifiableSparseIntArray {
+    private static final String TAG = "ImmutableSparseIntArray";
+
+    private final SparseIntArray mArray;
+
+    public UnmodifiableSparseIntArray(SparseIntArray array) {
+        mArray = array;
+    }
+
+    public int size() {
+        return mArray.size();
+    }
+
+    public int get(int key) {
+        return mArray.get(key);
+    }
+
+    public int get(int key, int valueIfKeyNotFound) {
+        return mArray.get(key, valueIfKeyNotFound);
+    }
+
+    public int keyAt(int index) {
+        return mArray.keyAt(index);
+    }
+
+    public int valueAt(int index) {
+        return mArray.valueAt(index);
+    }
+
+    public int indexOfValue(int value) {
+        return mArray.indexOfValue(value);
+    }
+
+    @Override
+    public String toString() {
+        return mArray.toString();
+    }
+}
diff --git a/services/core/java/com/android/server/hdmi/VolumeControlAction.java b/services/core/java/com/android/server/hdmi/VolumeControlAction.java
index e32b792..01c6f3e 100644
--- a/services/core/java/com/android/server/hdmi/VolumeControlAction.java
+++ b/services/core/java/com/android/server/hdmi/VolumeControlAction.java
@@ -28,7 +28,7 @@
  * from Audio Receiver(AVR). If TV receives no &lt;Report Audio Status&gt; from AVR, this action
  * will be finished in {@link #IRT_MS} * {@link #VOLUME_CHANGE_TIMEOUT_MAX_COUNT} (ms).
  */
-final class VolumeControlAction extends FeatureAction {
+final class VolumeControlAction extends HdmiCecFeatureAction {
     private static final String TAG = "VolumeControlAction";
 
     private static final int VOLUME_MUTE = 101;
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 0f5805c..7c1681c 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -235,6 +235,9 @@
     /** Switch code: Microphone.  When set, microphone is inserted. */
     public static final int SW_MICROPHONE_INSERT = 0x04;
 
+    /** Switch code: Line out.  When set, Line out (hi-Z) is inserted. */
+    public static final int SW_LINEOUT_INSERT = 0x06;
+
     /** Switch code: Headphone/Microphone Jack.  When set, something is inserted. */
     public static final int SW_JACK_PHYSICAL_INSERT = 0x07;
 
@@ -242,9 +245,10 @@
     public static final int SW_KEYPAD_SLIDE_BIT = 1 << SW_KEYPAD_SLIDE;
     public static final int SW_HEADPHONE_INSERT_BIT = 1 << SW_HEADPHONE_INSERT;
     public static final int SW_MICROPHONE_INSERT_BIT = 1 << SW_MICROPHONE_INSERT;
+    public static final int SW_LINEOUT_INSERT_BIT = 1 << SW_LINEOUT_INSERT;
     public static final int SW_JACK_PHYSICAL_INSERT_BIT = 1 << SW_JACK_PHYSICAL_INSERT;
     public static final int SW_JACK_BITS =
-            SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_JACK_PHYSICAL_INSERT_BIT;
+            SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_JACK_PHYSICAL_INSERT_BIT | SW_LINEOUT_INSERT_BIT;
 
     /** Whether to use the dev/input/event or uevent subsystem for the audio jack. */
     final boolean mUseDevInputEventForAudioJack;
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 9ac90dc..14457ec 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -74,7 +74,7 @@
     static final boolean DEBUG = true;
     /** The number of concurrent jobs we run at one time. */
     private static final int MAX_JOB_CONTEXTS_COUNT = 3;
-    static final String TAG = "JobManagerService";
+    static final String TAG = "JobSchedulerService";
     /** Master list of jobs. */
     final JobStore mJobs;
 
@@ -88,6 +88,11 @@
      */
     static final int MIN_IDLE_COUNT = 1;
     /**
+     * Minimum # of charging jobs that must be ready in order to force the JMS to schedule things
+     * early.
+     */
+    static final int MIN_CHARGING_COUNT = 1;
+    /**
      * Minimum # of connectivity jobs that must be ready in order to force the JMS to schedule
      * things early.
      */
@@ -95,8 +100,9 @@
     /**
      * Minimum # of jobs (with no particular constraints) for which the JMS will be happy running
      * some work early.
+     * This is correlated with the amount of batching we'll be able to do.
      */
-    static final int MIN_READY_JOBS_COUNT = 4;
+    static final int MIN_READY_JOBS_COUNT = 2;
 
     /**
      * Track Services that have currently active or pending jobs. The index is provided by
@@ -546,7 +552,8 @@
          */
         private void maybeQueueReadyJobsForExecutionH() {
             synchronized (mJobs) {
-                int idleCount = 0;
+                int chargingCount = 0;
+                int idleCount =  0;
                 int backoffCount = 0;
                 int connectivityCount = 0;
                 List<JobStatus> runnableJobs = new ArrayList<JobStatus>();
@@ -563,17 +570,34 @@
                         if (job.hasConnectivityConstraint() || job.hasUnmeteredConstraint()) {
                             connectivityCount++;
                         }
+                        if (job.hasChargingConstraint()) {
+                            chargingCount++;
+                        }
                         runnableJobs.add(job);
                     } else if (isReadyToBeCancelledLocked(job)) {
                         stopJobOnServiceContextLocked(job);
                     }
                 }
-                if (backoffCount > 0 || idleCount >= MIN_IDLE_COUNT ||
+                if (backoffCount > 0 ||
+                        idleCount >= MIN_IDLE_COUNT ||
                         connectivityCount >= MIN_CONNECTIVITY_COUNT ||
+                        chargingCount >= MIN_CHARGING_COUNT ||
                         runnableJobs.size() >= MIN_READY_JOBS_COUNT) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "maybeQueueReadyJobsForExecutionH: Running jobs.");
+                    }
                     for (int i=0; i<runnableJobs.size(); i++) {
                         mPendingJobs.add(runnableJobs.get(i));
                     }
+                } else {
+                    if (DEBUG) {
+                        Slog.d(TAG, "maybeQueueReadyJobsForExecutionH: Not running anything.");
+                    }
+                }
+                if (DEBUG) {
+                    Slog.d(TAG, "idle=" + idleCount + " connectivity=" +
+                    connectivityCount + " charging=" + chargingCount + " tot=" +
+                            runnableJobs.size());
                 }
             }
         }
diff --git a/services/core/java/com/android/server/job/controllers/IdleController.java b/services/core/java/com/android/server/job/controllers/IdleController.java
index 2213934..7b71027 100644
--- a/services/core/java/com/android/server/job/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -113,12 +113,13 @@
         public IdlenessTracker() {
             mAlarm = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
 
-            Intent intent = new Intent(ACTION_TRIGGER_IDLE);
-            intent.setComponent(new ComponentName(mContext, this.getClass()));
+            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
+                    .setPackage("android")
+                    .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
             mIdleTriggerIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
 
-            // at boot we presume that the user has just "interacted" with the
-            // device in some meaningful way
+            // At boot we presume that the user has just "interacted" with the
+            // device in some meaningful way.
             mIdle = false;
         }
 
@@ -163,9 +164,11 @@
                 // when the screen goes off or dreaming starts, we schedule the
                 // alarm that will tell us when we have decided the device is
                 // truly idle.
-                long when = SystemClock.elapsedRealtime() + INACTIVITY_IDLE_THRESHOLD;
+                final long nowElapsed = SystemClock.elapsedRealtime();
+                final long when = nowElapsed + INACTIVITY_IDLE_THRESHOLD;
                 if (DEBUG) {
-                    Slog.v(TAG, "Scheduling idle : " + action + " when=" + when);
+                    Slog.v(TAG, "Scheduling idle : " + action + " now:" + nowElapsed + " when="
+                            + when);
                 }
                 mAlarm.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                         when, IDLE_WINDOW_SLOP, mIdleTriggerIntent);
diff --git a/services/core/java/com/android/server/location/FlpHardwareProvider.java b/services/core/java/com/android/server/location/FlpHardwareProvider.java
index 495d3a9..530ad4b 100644
--- a/services/core/java/com/android/server/location/FlpHardwareProvider.java
+++ b/services/core/java/com/android/server/location/FlpHardwareProvider.java
@@ -272,8 +272,7 @@
             synchronized (mLocationSinkLock) {
                 // only one sink is allowed at the moment
                 if (mLocationSink != null) {
-                    throw new RuntimeException(
-                            "IFusedLocationHardware does not support multiple sinks");
+                    Log.e(TAG, "Replacing an existing IFusedLocationHardware sink");
                 }
 
                 mLocationSink = eventSink;
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 2f1bd60..d71f66a 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -431,9 +431,9 @@
 
     private String getShortMetadataString() {
         int fields = mMetadata == null ? 0 : mMetadata.size();
-        String title = mMetadata == null ? null : mMetadata
-                .getString(MediaMetadata.METADATA_KEY_TITLE);
-        return "size=" + fields + ", title=" + title;
+        MediaMetadata.Description description = mMetadata == null ? null : mMetadata
+                .getDescription();
+        return "size=" + fields + ", description=" + description;
     }
 
     private void pushPlaybackStateUpdate() {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 53006f3..743abc8 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -709,6 +709,7 @@
             } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
                 // turn off LED when user passes through lock screen
                 mNotificationLight.turnOff();
+                mStatusBar.notificationLightOff();
             } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
                 // reload per-user settings
                 mSettingsObserver.update(null);
@@ -1442,7 +1443,8 @@
                         }
                         pw.println("  ");
                     }
-
+                    pw.println("  mUseAttentionLight=" + mUseAttentionLight);
+                    pw.println("  mNotificationPulseEnabled=" + mNotificationPulseEnabled);
                     pw.println("  mSoundNotification=" + mSoundNotification);
                     pw.println("  mVibrateNotification=" + mVibrateNotification);
                     pw.println("  mDisableNotificationAlerts=" + mDisableNotificationAlerts);
@@ -1640,7 +1642,23 @@
 
                     applyZenModeLocked(r);
 
-                    mRankingHelper.sort(mNotificationList);
+                    try {
+                        mRankingHelper.sort(mNotificationList);
+                    } catch (RuntimeException ex) {
+                        // Don't crash the system server if something bad happened.
+                        Log.e(TAG, "Extreme badness during notification sort", ex);
+                        Log.e(TAG, "Current notification list: ");
+                        for (int ii=0; ii < mNotificationList.size(); ii++) {
+                            NotificationRecord nr = mNotificationList.get(ii);
+                            Log.e(TAG, String.format(
+                                    "  [%d] %s (group %s, rank %d, sortkey %s, proxy %s)",
+                                    ii, nr, nr.getGroupKey(), nr.getAuthoritativeRank(),
+                                    nr.getNotification().getSortKey(),
+                                    nr.getRankingProxy()));
+                        }
+                        // STOPSHIP: remove once b/16626175 is found
+                        throw ex;
+                    }
 
                     if (notification.icon != 0) {
                         StatusBarNotification oldSbn = (old != null) ? old.sbn : null;
@@ -2376,6 +2394,7 @@
         // Don't flash while we are in a call or screen is on
         if (mLedNotification == null || mInCall || mScreenOn) {
             mNotificationLight.turnOff();
+            mStatusBar.notificationLightOff();
         } else {
             final Notification ledno = mLedNotification.sbn.getNotification();
             int ledARGB = ledno.ledARGB;
@@ -2390,6 +2409,7 @@
                 // pulse repeatedly
                 mNotificationLight.setFlashing(ledARGB, Light.LIGHT_FLASH_TIMED,
                         ledOnMS, ledOffMS);
+                mStatusBar.notificationLightPulse(ledARGB, ledOnMS, ledOffMS);
             }
         }
     }
@@ -2507,10 +2527,7 @@
         if (!listener.enabledAndUserMatches(sbn.getUserId())) {
             return false;
         }
-        Notification n = sbn.getNotification();
-        if (listener.targetSdkVersion < Build.VERSION_CODES.L && n.isGroupChild())  {
-            return false;
-        }
+        // TODO: remove this for older listeners.
         return true;
     }
 
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index fefa6f6..0186b8c 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -211,7 +211,7 @@
     }
 
     public void setPackagePriority(int packagePriority) {
-      mPackagePriority = packagePriority;
+        mPackagePriority = packagePriority;
     }
 
     public int getPackagePriority() {
diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java
index 9b56464..4a7a971 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -468,7 +468,7 @@
         private static final int MSG_DISMISS = 4;
 
         private static final String DB_NAME = "notification_log.db";
-        private static final int DB_VERSION = 3;
+        private static final int DB_VERSION = 4;
 
         /** Age in ms after which events are pruned from the DB. */
         private static final long HORIZON_MS = 7 * 24 * 60 * 60 * 1000L;  // 1 week
@@ -559,32 +559,19 @@
                             COL_CATEGORY + " TEXT," +
                             COL_ACTION_COUNT + " INT," +
                             COL_POSTTIME_MS + " INT," +
-                            COL_AIRTIME_MS + " INT" +
-                            COL_FIRST_EXPANSIONTIME_MS + " INT" +
-                            COL_AIRTIME_EXPANDED_MS + " INT" +
+                            COL_AIRTIME_MS + " INT," +
+                            COL_FIRST_EXPANSIONTIME_MS + " INT," +
+                            COL_AIRTIME_EXPANDED_MS + " INT," +
                             COL_EXPAND_COUNT + " INT" +
                             ")");
                 }
 
                 @Override
                 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-                    switch (oldVersion) {
-                        case 1:
-                            // Add COL_POSTTIME_MS, COL_AIRTIME_MS columns,
-                            db.execSQL("ALTER TABLE " + TAB_LOG + " ADD COLUMN " +
-                                    COL_POSTTIME_MS + " INT");
-                            db.execSQL("ALTER TABLE " + TAB_LOG + " ADD COLUMN " +
-                                    COL_AIRTIME_MS + " INT");
-                        case 2:
-                            // Add COL_EXPANSIONTIME_MS column
-                            db.execSQL("ALTER TABLE " + TAB_LOG + " ADD COLUMN " +
-                                    COL_FIRST_EXPANSIONTIME_MS + " INT");
-                            // Add COL_AIRTIME_EXPANDED_MS column
-                            db.execSQL("ALTER TABLE " + TAB_LOG + " ADD COLUMN " +
-                                    COL_AIRTIME_EXPANDED_MS + " INT");
-                            // Add COL_EXPAND_COUNT column
-                            db.execSQL("ALTER TABLE " + TAB_LOG + " ADD COLUMN " +
-                                    COL_EXPAND_COUNT + " INT");
+                    if (oldVersion <= 3) {
+                        // Version 3 creation left 'log' in a weird state. Just reset for now.
+                        db.execSQL("DROP TABLE IF EXISTS " + TAB_LOG);
+                        onCreate(db);
                     }
                 }
             };
diff --git a/services/core/java/com/android/server/notification/PackagePriorityExtractor.java b/services/core/java/com/android/server/notification/PackagePriorityExtractor.java
index 9cdb3e1..a13e54a 100644
--- a/services/core/java/com/android/server/notification/PackagePriorityExtractor.java
+++ b/services/core/java/com/android/server/notification/PackagePriorityExtractor.java
@@ -15,7 +15,6 @@
 */
 package com.android.server.notification;
 
-import android.app.Notification;
 import android.content.Context;
 import android.util.Slog;
 
diff --git a/services/core/java/com/android/server/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java
index 64efa67..b22ed2d 100644
--- a/services/core/java/com/android/server/notification/ZenLog.java
+++ b/services/core/java/com/android/server/notification/ZenLog.java
@@ -58,6 +58,7 @@
     private static final int TYPE_UNSUBSCRIBE = 8;
     private static final int TYPE_CONFIG = 9;
     private static final int TYPE_FOLLOW_RINGER_MODE = 10;
+    private static final int TYPE_NOT_INTERCEPTED = 11;
 
     private static int sNext;
     private static int sSize;
@@ -67,6 +68,11 @@
         append(TYPE_INTERCEPTED, record.getKey() + "," + reason);
     }
 
+    public static void traceNotIntercepted(NotificationRecord record, String reason) {
+        if (record != null && record.isUpdate) return;  // already logged
+        append(TYPE_NOT_INTERCEPTED, record.getKey() + "," + reason);
+    }
+
     public static void traceAllowDisable(String pkg, boolean allowDisable, String reason) {
         if (SYSTEM_PACKAGES.contains(pkg)) return;
         append(TYPE_ALLOW_DISABLE, allowDisable + "," + pkg + "," + reason);
@@ -122,6 +128,7 @@
             case TYPE_UNSUBSCRIBE: return "unsubscribe";
             case TYPE_CONFIG: return "config";
             case TYPE_FOLLOW_RINGER_MODE: return "follow_ringer_mode";
+            case TYPE_NOT_INTERCEPTED: return "not_intercepted";
             default: return "unknown";
         }
     }
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 6b55213..9f97583 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -137,6 +137,13 @@
                 }
                 return false;
             }
+            // allow user-prioritized packages through in priority mode
+            if (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
+                if (record.getPackagePriority() == Notification.PRIORITY_MAX) {
+                    ZenLog.traceNotIntercepted(record, "priorityApp");
+                    return false;
+                }
+            }
             // audience has veto power over all following rules
             if (!audienceMatches(record)) {
                 ZenLog.traceIntercepted(record, "!audienceMatches");
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 8b0a46d..b261ef5 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -212,6 +212,34 @@
         return execute(builder.toString());
     }
 
+    public int patchoat(String apkPath, int uid, boolean isPublic, String pkgName,
+            String instructionSet) {
+        StringBuilder builder = new StringBuilder("patchoat");
+        builder.append(' ');
+        builder.append(apkPath);
+        builder.append(' ');
+        builder.append(uid);
+        builder.append(isPublic ? " 1" : " 0");
+        builder.append(' ');
+        builder.append(pkgName);
+        builder.append(' ');
+        builder.append(instructionSet);
+        return execute(builder.toString());
+    }
+
+    public int patchoat(String apkPath, int uid, boolean isPublic, String instructionSet) {
+        StringBuilder builder = new StringBuilder("patchoat");
+        builder.append(' ');
+        builder.append(apkPath);
+        builder.append(' ');
+        builder.append(uid);
+        builder.append(isPublic ? " 1" : " 0");
+        builder.append(" *");         // No pkgName arg present
+        builder.append(' ');
+        builder.append(instructionSet);
+        return execute(builder.toString());
+    }
+
     public int dexopt(String apkPath, int uid, boolean isPublic, String instructionSet) {
         StringBuilder builder = new StringBuilder("dexopt");
         builder.append(' ');
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 1650768..b4faea1 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -38,6 +38,7 @@
 import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageDeleteObserver2;
 import android.content.pm.IPackageInstaller;
 import android.content.pm.IPackageInstallerCallback;
 import android.content.pm.IPackageInstallerSession;
@@ -121,8 +122,12 @@
     private static final String ATTR_REFERRER_URI = "referrerUri";
     private static final String ATTR_ABI_OVERRIDE = "abiOverride";
 
+    /** Automatically destroy sessions older than this */
     private static final long MAX_AGE_MILLIS = 3 * DateUtils.DAY_IN_MILLIS;
+    /** Upper bound on number of active sessions for a UID */
     private static final long MAX_ACTIVE_SESSIONS = 1024;
+    /** Upper bound on number of historical sessions for a UID */
+    private static final long MAX_HISTORICAL_SESSIONS = 1048576;
 
     private final Context mContext;
     private final PackageManagerService mPm;
@@ -410,9 +415,15 @@
         final PackageInstallerSession session;
         synchronized (mSessions) {
             // Sanity check that installer isn't going crazy
-            final int activeCount = getSessionCountLocked(callingUid);
+            final int activeCount = getSessionCount(mSessions, callingUid);
             if (activeCount >= MAX_ACTIVE_SESSIONS) {
-                throw new IllegalStateException("Too many active sessions for UID " + callingUid);
+                throw new IllegalStateException(
+                        "Too many active sessions for UID " + callingUid);
+            }
+            final int historicalCount = getSessionCount(mHistoricalSessions, callingUid);
+            if (historicalCount >= MAX_HISTORICAL_SESSIONS) {
+                throw new IllegalStateException(
+                        "Too many historical sessions for UID " + callingUid);
             }
 
             sessionId = allocateSessionIdLocked();
@@ -452,8 +463,8 @@
         int n = 0;
         int sessionId;
         do {
-            sessionId = mRandom.nextInt(Integer.MAX_VALUE);
-            if (mSessions.get(sessionId) == null) {
+            sessionId = mRandom.nextInt(Integer.MAX_VALUE - 1) + 1;
+            if (mSessions.get(sessionId) == null && mHistoricalSessions.get(sessionId) == null) {
                 return sessionId;
             }
         } while (n++ < 32);
@@ -530,17 +541,17 @@
     }
 
     @Override
-    public void uninstall(String packageName, int flags, IPackageDeleteObserver observer,
+    public void uninstall(String packageName, int flags, IPackageDeleteObserver2 observer,
             int userId) {
         mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "uninstall");
 
         // TODO: enforce installer of record or permission
-        mPm.deletePackageAsUser(packageName, observer, userId, flags);
+        mPm.deletePackage(packageName, observer, userId, flags);
     }
 
     @Override
     public void uninstallSplit(String basePackageName, String overlayName, int flags,
-            IPackageDeleteObserver observer, int userId) {
+            IPackageDeleteObserver2 observer, int userId) {
         mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "uninstallSplit");
 
         // TODO: flesh out once PM has split support
@@ -560,11 +571,12 @@
         mCallbacks.unregister(callback);
     }
 
-    private int getSessionCountLocked(int installerUid) {
+    private static int getSessionCount(SparseArray<PackageInstallerSession> sessions,
+            int installerUid) {
         int count = 0;
-        final int size = mSessions.size();
+        final int size = sessions.size();
         for (int i = 0; i < size; i++) {
-            final PackageInstallerSession session = mSessions.valueAt(i);
+            final PackageInstallerSession session = sessions.valueAt(i);
             if (session.installerUid == installerUid) {
                 count++;
             }
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 26019db..5443fbc 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -24,6 +24,7 @@
 import static android.system.OsConstants.O_RDONLY;
 import static android.system.OsConstants.O_WRONLY;
 
+import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.IPackageInstallerSession;
@@ -134,8 +135,8 @@
                     Slog.e(TAG, "Install failed: " + e);
                     destroyInternal();
                     try {
-                        mRemoteObserver.packageInstalled(mPackageName, null, e.error,
-                                e.getMessage());
+                        mRemoteObserver.onPackageInstalled(mPackageName, e.error, e.getMessage(),
+                                null);
                     } catch (RemoteException ignored) {
                     }
                     mCallback.onSessionFinished(PackageInstallerSession.this, false);
@@ -377,11 +378,16 @@
         final IPackageInstallObserver2 remoteObserver = mRemoteObserver;
         final IPackageInstallObserver2 localObserver = new IPackageInstallObserver2.Stub() {
             @Override
-            public void packageInstalled(String basePackageName, Bundle extras, int returnCode,
-                    String msg) {
+            public void onUserActionRequired(Intent intent) {
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
+                    Bundle extras) {
                 destroyInternal();
                 try {
-                    remoteObserver.packageInstalled(basePackageName, extras, returnCode, msg);
+                    remoteObserver.onPackageInstalled(basePackageName, returnCode, msg, extras);
                 } catch (RemoteException ignored) {
                 }
                 final boolean success = (returnCode == PackageManager.INSTALL_SUCCEEDED);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 2b55bf5..4bf6636 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -85,6 +85,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
+import android.app.PackageDeleteObserver;
 import android.app.admin.IDevicePolicyManager;
 import android.app.backup.IBackupManager;
 import android.content.BroadcastReceiver;
@@ -101,6 +102,7 @@
 import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageDeleteObserver2;
 import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.IPackageInstaller;
 import android.content.pm.IPackageManager;
@@ -1063,8 +1065,8 @@
                         if (args.observer != null) {
                             try {
                                 Bundle extras = extrasForInstallResult(res);
-                                args.observer.packageInstalled(res.name, extras, res.returnCode,
-                                        res.returnMsg);
+                                args.observer.onPackageInstalled(res.name, res.returnCode,
+                                        res.returnMsg, extras);
                             } catch (RemoteException e) {
                                 Slog.i(TAG, "Observer no longer exists.");
                             }
@@ -1418,11 +1420,18 @@
                         }
 
                         try {
-                            if (DexFile.isDexOptNeededInternal(lib, null, instructionSet, false)) {
+                            byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null,
+                                                                                 instructionSet,
+                                                                                 false);
+                            if (dexoptRequired != DexFile.UP_TO_DATE) {
                                 alreadyDexOpted.add(lib);
 
                                 // The list of "shared libraries" we have at this point is
-                                mInstaller.dexopt(lib, Process.SYSTEM_UID, true, instructionSet);
+                                if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
+                                    mInstaller.dexopt(lib, Process.SYSTEM_UID, true, instructionSet);
+                                } else {
+                                    mInstaller.patchoat(lib, Process.SYSTEM_UID, true, instructionSet);
+                                }
                                 didDexOptLibraryOrTool = true;
                             }
                         } catch (FileNotFoundException e) {
@@ -1469,9 +1478,15 @@
                             continue;
                         }
                         try {
-                            if (DexFile.isDexOptNeededInternal(path, null, instructionSet, false)) {
+                            byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null,
+                                                                                 instructionSet,
+                                                                                 false);
+                            if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
                                 mInstaller.dexopt(path, Process.SYSTEM_UID, true, instructionSet);
                                 didDexOptLibraryOrTool = true;
+                            } else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) {
+                                mInstaller.patchoat(path, Process.SYSTEM_UID, true, instructionSet);
+                                didDexOptLibraryOrTool = true;
                             }
                         } catch (FileNotFoundException e) {
                             Slog.w(TAG, "Jar not found: " + path);
@@ -4623,9 +4638,14 @@
                 }
 
                 try {
-                    final boolean isDexOptNeeded = DexFile.isDexOptNeededInternal(path,
+                    // This will return DEXOPT_NEEDED if we either cannot find any odex file for this
+                    // patckage or the one we find does not match the image checksum (i.e. it was
+                    // compiled against an old image). It will return PATCHOAT_NEEDED if we can find a
+                    // odex file and it matches the checksum of the image but not its base address,
+                    // meaning we need to move it.
+                    final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path,
                             pkg.packageName, instructionSet, defer);
-                    if (forceDex || (!defer && isDexOptNeeded)) {
+                    if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) {
                         Log.i(TAG, "Running dexopt on: " + path + " pkg="
                                 + pkg.applicationInfo.packageName + " isa=" + instructionSet);
                         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
@@ -4641,12 +4661,27 @@
                             performedDexOpt = true;
                             pkg.mDexOptPerformed.add(instructionSet);
                         }
+                    } else if (!defer && isDexOptNeeded == DexFile.PATCHOAT_NEEDED) {
+                        Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName);
+                        final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
+                        final int ret = mInstaller.patchoat(path, sharedGid, !isForwardLocked(pkg),
+                                pkg.packageName, instructionSet);
+
+                        if (ret < 0) {
+                            // Don't bother running patchoat again if we failed, it will probably
+                            // just result in an error again. Also, don't bother dexopting for other
+                            // paths & ISAs.
+                            return DEX_OPT_FAILED;
+                        } else {
+                            performedDexOpt = true;
+                            pkg.mDexOptPerformed.add(instructionSet);
+                        }
                     }
 
                     // We're deciding to defer a needed dexopt. Don't bother dexopting for other
                     // paths and instruction sets. We'll deal with them all together when we process
                     // our list of deferred dexopts.
-                    if (defer && isDexOptNeeded) {
+                    if (defer && isDexOptNeeded != DexFile.UP_TO_DATE) {
                         if (mDeferredDexOpt == null) {
                             mDeferredDexOpt = new HashSet<PackageParser.Package>();
                         }
@@ -7723,7 +7758,7 @@
         if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) {
             try {
                 if (observer != null) {
-                    observer.packageInstalled("", null, INSTALL_FAILED_USER_RESTRICTED, null);
+                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
                 }
             } catch (RemoteException re) {
             }
@@ -10486,9 +10521,15 @@
     }
 
     @Override
-    public void deletePackageAsUser(final String packageName,
-                                    final IPackageDeleteObserver observer,
-                                    final int userId, final int flags) {
+    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
+            int flags) {
+        deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
+                flags);
+    }
+
+    @Override
+    public void deletePackage(final String packageName,
+            final IPackageDeleteObserver2 observer, final int userId, final int flags) {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.DELETE_PACKAGES, null);
         final int uid = Binder.getCallingUid();
@@ -10499,7 +10540,8 @@
         }
         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
             try {
-                observer.packageDeleted(packageName, PackageManager.DELETE_FAILED_USER_RESTRICTED);
+                observer.onPackageDeleted(packageName,
+                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
             } catch (RemoteException re) {
             }
             return;
@@ -10519,7 +10561,8 @@
         }
         if (uninstallBlocked) {
             try {
-                observer.packageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED);
+                observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED,
+                        null);
             } catch (RemoteException re) {
             }
             return;
@@ -10535,7 +10578,7 @@
                 final int returnCode = deletePackageX(packageName, userId, flags);
                 if (observer != null) {
                     try {
-                        observer.packageDeleted(packageName, returnCode);
+                        observer.onPackageDeleted(packageName, returnCode, null);
                     } catch (RemoteException e) {
                         Log.i(TAG, "Observer no longer exists.");
                     } //end catch
@@ -11410,7 +11453,7 @@
 
     @Override
     public void replacePreferredActivity(IntentFilter filter, int match,
-            ComponentName[] set, ComponentName activity) {
+            ComponentName[] set, ComponentName activity, int userId) {
         if (filter.countActions() != 1) {
             throw new IllegalArgumentException(
                     "replacePreferredActivity expects filter to have only 1 action.");
@@ -11423,11 +11466,15 @@
                     "replacePreferredActivity expects filter to have no data authorities, " +
                     "paths, or types; and at most one scheme.");
         }
+
+        final int callingUid = Binder.getCallingUid();
+        enforceCrossUserPermission(callingUid, userId, true, "replace preferred activity");
+        final int callingUserId = UserHandle.getUserId(callingUid);
         synchronized (mPackages) {
             if (mContext.checkCallingOrSelfPermission(
                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
                     != PackageManager.PERMISSION_GRANTED) {
-                if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
+                if (getUidTargetSdkVersionLockedLPr(callingUid)
                         < Build.VERSION_CODES.FROYO) {
                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
                             + Binder.getCallingUid());
@@ -11437,7 +11484,6 @@
                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
             }
 
-            final int callingUserId = UserHandle.getCallingUserId();
             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(callingUserId);
             if (pir != null) {
                 Intent intent = new Intent(filter.getAction(0)).addCategory(filter.getCategory(0));
@@ -11666,6 +11712,7 @@
         mSettings.writePackageRestrictionsLPr(sourceUserId);
     }
 
+    @Override
     public void removeCrossProfileIntentsForPackage(String packageName,
             int sourceUserId, int targetUserId) {
         mContext.enforceCallingOrSelfPermission(
@@ -13403,4 +13450,20 @@
             return false;
         }
     }
+
+    private static class LegacyPackageDeleteObserver extends PackageDeleteObserver {
+        private final IPackageDeleteObserver mLegacy;
+
+        public LegacyPackageDeleteObserver(IPackageDeleteObserver legacy) {
+            mLegacy = legacy;
+        }
+
+        @Override
+        public void onPackageDeleted(String basePackageName, int returnCode, String msg) {
+            try {
+                mLegacy.packageDeleted(basePackageName, returnCode);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 8c52fad..d1182e9 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -422,6 +422,9 @@
     // Current state of whether the settings are allowing auto low power mode.
     private boolean mAutoLowPowerModeEnabled;
 
+   // The user turned off low power mode below the trigger level
+    private boolean mAutoLowPowerModeSnoozing;
+
     // True if the battery level is currently considered low.
     private boolean mBatteryLevelLow;
 
@@ -650,9 +653,23 @@
         final boolean lowPowerModeEnabled = Settings.Global.getInt(resolver,
                 Settings.Global.LOW_POWER_MODE, 0) != 0;
         final boolean autoLowPowerModeEnabled = Settings.Global.getInt(resolver,
-                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 15) != 0;
+                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0) != 0;
         if (lowPowerModeEnabled != mLowPowerModeSetting
                 || autoLowPowerModeEnabled != mAutoLowPowerModeEnabled) {
+            if (lowPowerModeEnabled != mLowPowerModeSetting) {
+                if (!mAutoLowPowerModeSnoozing && !lowPowerModeEnabled && !mIsPowered
+                        && mAutoLowPowerModeEnabled) {
+                    if (DEBUG_SPEW) {
+                        Slog.d(TAG, "updateSettingsLocked: snoozing low power mode");
+                    }
+                    mAutoLowPowerModeSnoozing = true;
+                } else if (mAutoLowPowerModeSnoozing && lowPowerModeEnabled) {
+                    if (DEBUG_SPEW) {
+                        Slog.d(TAG, "updateSettingsLocked: no longer snoozing low power mode");
+                    }
+                    mAutoLowPowerModeSnoozing = true;
+                }
+            }
             mLowPowerModeSetting = lowPowerModeEnabled;
             mAutoLowPowerModeEnabled = autoLowPowerModeEnabled;
             updateLowPowerModeLocked();
@@ -662,8 +679,25 @@
     }
 
     void updateLowPowerModeLocked() {
-        final boolean lowPowerModeEnabled = !mIsPowered
-                && (mLowPowerModeSetting || (mAutoLowPowerModeEnabled && mBatteryLevelLow));
+        if (mIsPowered && mLowPowerModeSetting) {
+            if (DEBUG_SPEW) {
+                Slog.d(TAG, "updateLowPowerModeLocked: powered, turning setting off");
+            }
+            // Turn setting off if powered
+            Settings.Global.putInt(mContext.getContentResolver(),
+                    Settings.Global.LOW_POWER_MODE, 0);
+            mLowPowerModeSetting = false;
+        } else if (!mIsPowered && mAutoLowPowerModeEnabled && !mAutoLowPowerModeSnoozing
+                && mBatteryLevelLow && !mLowPowerModeSetting) {
+            if (DEBUG_SPEW) {
+                Slog.d(TAG, "updateLowPowerModeLocked: trigger level reached, turning setting on");
+            }
+            // Turn setting on if trigger level is enabled, and we're now below it
+            Settings.Global.putInt(mContext.getContentResolver(),
+                    Settings.Global.LOW_POWER_MODE, 1);
+            mLowPowerModeSetting = true;
+        }
+        final boolean lowPowerModeEnabled = mLowPowerModeSetting;
         if (mLowPowerModeEnabled != lowPowerModeEnabled) {
             mLowPowerModeEnabled = lowPowerModeEnabled;
             powerHintInternal(POWER_HINT_LOW_POWER_MODE, lowPowerModeEnabled ? 1 : 0);
@@ -672,6 +706,10 @@
             BackgroundThread.getHandler().post(new Runnable() {
                 @Override
                 public void run() {
+                    Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING)
+                            .putExtra(PowerManager.EXTRA_POWER_SAVE_MODE, mLowPowerModeEnabled)
+                            .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+                    mContext.sendBroadcast(intent);
                     ArrayList<PowerManagerInternal.LowPowerModeListener> listeners;
                     synchronized (mLock) {
                         listeners = new ArrayList<PowerManagerInternal.LowPowerModeListener>(
@@ -680,7 +718,7 @@
                     for (int i=0; i<listeners.size(); i++) {
                         listeners.get(i).onLowPowerModeChanged(lowPowerModeEnabled);
                     }
-                    Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
+                    intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                     mContext.sendBroadcast(intent);
                 }
@@ -1218,6 +1256,12 @@
             }
 
             if (wasPowered != mIsPowered || oldLevelLow != mBatteryLevelLow) {
+                if (oldLevelLow != mBatteryLevelLow && !mBatteryLevelLow) {
+                    if (DEBUG_SPEW) {
+                        Slog.d(TAG, "updateIsPoweredLocked: resetting low power snooze");
+                    }
+                    mAutoLowPowerModeSnoozing = false;
+                }
                 updateLowPowerModeLocked();
             }
         }
@@ -2265,6 +2309,7 @@
             pw.println("  mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting);
             pw.println("  mLowPowerModeSetting=" + mLowPowerModeSetting);
             pw.println("  mAutoLowPowerModeEnabled=" + mAutoLowPowerModeEnabled);
+            pw.println("  mAutoLowPowerModeSnoozing=" + mAutoLowPowerModeSnoozing);
             pw.println("  mMinimumScreenOffTimeoutConfig=" + mMinimumScreenOffTimeoutConfig);
             pw.println("  mMaximumScreenDimDurationConfig=" + mMaximumScreenDimDurationConfig);
             pw.println("  mMaximumScreenDimRatioConfig=" + mMaximumScreenDimRatioConfig);
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 463f763..c28e0bc 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -21,4 +21,6 @@
 public interface StatusBarManagerInternal {
     void setNotificationDelegate(NotificationDelegate delegate);
     void buzzBeepBlinked();
+    void notificationLightPulse(int argb, int onMillis, int offMillis);
+    void notificationLightOff();
 }
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index f33943d..21905f0 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -107,10 +107,13 @@
      * Private API used by NotificationManagerService.
      */
     private final StatusBarManagerInternal mInternalService = new StatusBarManagerInternal() {
+        private boolean mNotificationLightOn;
+
         @Override
         public void setNotificationDelegate(NotificationDelegate delegate) {
             mNotificationDelegate = delegate;
         }
+
         @Override
         public void buzzBeepBlinked() {
             if (mBar != null) {
@@ -120,6 +123,30 @@
                 }
             }
         }
+
+        @Override
+        public void notificationLightPulse(int argb, int onMillis, int offMillis) {
+            mNotificationLightOn = true;
+            if (mBar != null) {
+                try {
+                    mBar.notificationLightPulse(argb, onMillis, offMillis);
+                } catch (RemoteException ex) {
+                }
+            }
+        }
+
+        @Override
+        public void notificationLightOff() {
+            if (mNotificationLightOn) {
+                mNotificationLightOn = false;
+                if (mBar != null) {
+                    try {
+                        mBar.notificationLightOff();
+                    } catch (RemoteException ex) {
+                    }
+                }
+            }
+        }
     };
 
     // ================================================================================
@@ -426,10 +453,10 @@
     }
 
     @Override
-    public void hideRecentApps(boolean triggeredFromAltTab) {
+    public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
         if (mBar != null) {
             try {
-                mBar.hideRecentApps(triggeredFromAltTab);
+                mBar.hideRecentApps(triggeredFromAltTab, triggeredFromHomeKey);
             } catch (RemoteException ex) {}
         }
     }
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 80ea2c8..74f725f 100644
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -21,13 +21,16 @@
 
 import android.content.Context;
 import android.content.Intent;
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.HdmiHotplugEvent;
 import android.hardware.hdmi.IHdmiControlService;
 import android.hardware.hdmi.IHdmiDeviceEventListener;
 import android.hardware.hdmi.IHdmiHotplugEventListener;
 import android.hardware.hdmi.IHdmiInputChangeListener;
 import android.media.AudioDevicePort;
+import android.media.AudioFormat;
+import android.media.AudioGain;
+import android.media.AudioGainConfig;
 import android.media.AudioManager;
 import android.media.AudioPatch;
 import android.media.AudioPort;
@@ -54,6 +57,7 @@
 import com.android.server.SystemService;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -78,7 +82,7 @@
     private final TvInputHal mHal = new TvInputHal(this);
     private final SparseArray<Connection> mConnections = new SparseArray<>();
     private final List<TvInputHardwareInfo> mHardwareList = new ArrayList<>();
-    private List<HdmiCecDeviceInfo> mHdmiCecDeviceList = new LinkedList<>();
+    private List<HdmiDeviceInfo> mHdmiCecDeviceList = new LinkedList<>();
     /* A map from a device ID to the matching TV input ID. */
     private final SparseArray<String> mHardwareInputIdMap = new SparseArray<>();
     /* A map from a HDMI logical address to the matching TV input ID. */
@@ -160,9 +164,9 @@
             TvInputHardwareInfo info = connection.getHardwareInfoLocked();
             if (info.getType() == TvInputHardwareInfo.TV_INPUT_TYPE_HDMI) {
                 // Remove HDMI CEC devices linked with this hardware.
-                for (Iterator<HdmiCecDeviceInfo> it = mHdmiCecDeviceList.iterator();
+                for (Iterator<HdmiDeviceInfo> it = mHdmiCecDeviceList.iterator();
                         it.hasNext(); ) {
-                    HdmiCecDeviceInfo deviceInfo = it.next();
+                    HdmiDeviceInfo deviceInfo = it.next();
                     if (deviceInfo.getPortId() == info.getHdmiPortId()) {
                         mHandler.obtainMessage(ListenerHandler.HDMI_CEC_DEVICE_REMOVED, 0, 0,
                                 deviceInfo).sendToTarget();
@@ -216,7 +220,7 @@
         }
     }
 
-    public List<HdmiCecDeviceInfo> getHdmiCecInputDeviceList() {
+    public List<HdmiDeviceInfo> getHdmiCecInputDeviceList() {
         synchronized (mLock) {
             return Collections.unmodifiableList(mHdmiCecDeviceList);
         }
@@ -446,7 +450,7 @@
     private void processPendingHdmiDeviceEventsLocked() {
         for (Iterator<Message> it = mPendingHdmiDeviceEvents.iterator(); it.hasNext(); ) {
             Message msg = it.next();
-            HdmiCecDeviceInfo deviceInfo = (HdmiCecDeviceInfo) msg.obj;
+            HdmiDeviceInfo deviceInfo = (HdmiDeviceInfo) msg.obj;
             TvInputHardwareInfo hardwareInfo =
                     findHardwareInfoForHdmiPortLocked(deviceInfo.getPortId());
             if (hardwareInfo != null) {
@@ -555,46 +559,93 @@
         private boolean mReleased = false;
         private final Object mImplLock = new Object();
 
-        private final AudioDevicePort mAudioSource;
-        private final AudioDevicePort mAudioSink;
-        private AudioPatch mAudioPatch = null;
-
-        private TvStreamConfig mActiveConfig = null;
-
-        public TvInputHardwareImpl(TvInputHardwareInfo info) {
-            mInfo = info;
-            AudioDevicePort audioSource = null;
-            AudioDevicePort audioSink = null;
-            if (mInfo.getAudioType() != AudioManager.DEVICE_NONE) {
-                ArrayList<AudioPort> devicePorts = new ArrayList<AudioPort>();
-                if (mAudioManager.listAudioDevicePorts(devicePorts) == AudioManager.SUCCESS) {
-                    // Find source
-                    for (AudioPort port : devicePorts) {
-                        AudioDevicePort devicePort = (AudioDevicePort) port;
-                        if (devicePort.type() == mInfo.getAudioType() &&
-                                devicePort.address().equals(mInfo.getAudioAddress())) {
-                            audioSource = devicePort;
-                            break;
-                        }
-                    }
-                    // Find sink
-                    // TODO: App may want to specify sink device?
-                    int sinkDevices = mAudioManager.getDevicesForStream(AudioManager.STREAM_MUSIC);
-                    for (AudioPort port : devicePorts) {
-                        AudioDevicePort devicePort = (AudioDevicePort) port;
-                        if (devicePort.type() == sinkDevices) {
-                            audioSink = devicePort;
-                            break;
+        private final AudioManager.OnAudioPortUpdateListener mAudioListener =
+                new AudioManager.OnAudioPortUpdateListener() {
+            @Override
+            public void onAudioPortListUpdate(AudioPort[] portList) {
+                synchronized (mImplLock) {
+                    updateAudioSinkLocked();
+                    if (mInfo.getAudioType() != AudioManager.DEVICE_NONE && mAudioSource == null) {
+                        mAudioSource = findAudioDevicePort(mInfo.getAudioType(),
+                                mInfo.getAudioAddress());
+                        if (mActiveConfig != null) {
+                            updateAudioPatchLocked();
                         }
                     }
                 }
             }
-            mAudioSource = audioSource;
-            mAudioSink = audioSink;
+
+            @Override
+            public void onAudioPatchListUpdate(AudioPatch[] patchList) {
+                // No-op
+            }
+
+            @Override
+            public void onServiceDied() {
+                synchronized (mImplLock) {
+                    mAudioSource = null;
+                    mAudioSink = null;
+                    mAudioPatch = null;
+                }
+            }
+        };
+        private int mOverrideAudioType = AudioManager.DEVICE_NONE;
+        private String mOverrideAudioAddress = "";
+        private AudioDevicePort mAudioSource;
+        private AudioDevicePort mAudioSink;
+        private AudioPatch mAudioPatch = null;
+        private float mCommittedVolume = 0.0f;
+        private float mVolume = 0.0f;
+
+        private TvStreamConfig mActiveConfig = null;
+
+        private int mDesiredSamplingRate = 0;
+        private int mDesiredChannelMask = AudioFormat.CHANNEL_OUT_DEFAULT;
+        private int mDesiredFormat = AudioFormat.ENCODING_DEFAULT;
+
+        public TvInputHardwareImpl(TvInputHardwareInfo info) {
+            mInfo = info;
+            mAudioManager.registerAudioPortUpdateListener(mAudioListener);
+            if (mInfo.getAudioType() != AudioManager.DEVICE_NONE) {
+                mAudioSource = findAudioDevicePort(mInfo.getAudioType(), mInfo.getAudioAddress());
+                mAudioSink = findAudioSinkFromAudioPolicy();
+            }
+        }
+
+        private AudioDevicePort findAudioSinkFromAudioPolicy() {
+            ArrayList<AudioPort> devicePorts = new ArrayList<AudioPort>();
+            if (mAudioManager.listAudioDevicePorts(devicePorts) == AudioManager.SUCCESS) {
+                int sinkDevice = mAudioManager.getDevicesForStream(AudioManager.STREAM_MUSIC);
+                for (AudioPort port : devicePorts) {
+                    AudioDevicePort devicePort = (AudioDevicePort) port;
+                    if (devicePort.type() == sinkDevice) {
+                        return devicePort;
+                    }
+                }
+            }
+            return null;
+        }
+
+        private AudioDevicePort findAudioDevicePort(int type, String address) {
+            if (type == AudioManager.DEVICE_NONE) {
+                return null;
+            }
+            ArrayList<AudioPort> devicePorts = new ArrayList<AudioPort>();
+            if (mAudioManager.listAudioDevicePorts(devicePorts) != AudioManager.SUCCESS) {
+                return null;
+            }
+            for (AudioPort port : devicePorts) {
+                AudioDevicePort devicePort = (AudioDevicePort) port;
+                if (devicePort.type() == type && devicePort.address().equals(address)) {
+                    return devicePort;
+                }
+            }
+            return null;
         }
 
         public void release() {
             synchronized (mImplLock) {
+                mAudioManager.unregisterAudioPortUpdateListener(mAudioListener);
                 if (mAudioPatch != null) {
                     mAudioManager.releaseAudioPatch(mAudioPatch);
                     mAudioPatch = null;
@@ -621,15 +672,7 @@
                 }
                 if (mAudioSource != null && mAudioSink != null) {
                     if (surface != null) {
-                        AudioPortConfig sourceConfig = mAudioSource.activeConfig();
-                        AudioPortConfig sinkConfig = mAudioSink.activeConfig();
-                        AudioPatch[] audioPatchArray = new AudioPatch[] { mAudioPatch };
-                        // TODO: build config if activeConfig() == null
-                        mAudioManager.createAudioPatch(
-                                audioPatchArray,
-                                new AudioPortConfig[] { sourceConfig },
-                                new AudioPortConfig[] { sinkConfig });
-                        mAudioPatch = audioPatchArray[0];
+                        updateAudioPatchLocked();
                     } else {
                         mAudioManager.releaseAudioPatch(mAudioPatch);
                         mAudioPatch = null;
@@ -656,14 +699,86 @@
             }
         }
 
+        private void updateAudioPatchLocked() {
+            if (mAudioSource == null || mAudioSink == null) {
+                if (mAudioPatch != null) {
+                    throw new IllegalStateException("Audio patch should be null if audio source "
+                            + "or sink is null.");
+                }
+                return;
+            }
+
+            AudioGainConfig sourceGainConfig = null;
+            if (mAudioSource.gains().length > 0 && mVolume != mCommittedVolume) {
+                AudioGain sourceGain = null;
+                for (AudioGain gain : mAudioSource.gains()) {
+                    if ((gain.mode() & AudioGain.MODE_JOINT) != 0) {
+                        sourceGain = gain;
+                        break;
+                    }
+                }
+                // NOTE: we only change the source gain in MODE_JOINT here.
+                if (sourceGain != null) {
+                    int steps = (sourceGain.maxValue() - sourceGain.minValue())
+                            / sourceGain.stepValue();
+                    int gainValue = sourceGain.minValue();
+                    if (mVolume < 1.0f) {
+                        gainValue += sourceGain.stepValue() * (int) (mVolume * steps + 0.5);
+                    } else {
+                        gainValue = sourceGain.maxValue();
+                    }
+                    int numChannels = 0;
+                    for (int mask = sourceGain.channelMask(); mask > 0; mask >>= 1) {
+                        numChannels += (mask & 1);
+                    }
+                    int[] gainValues = new int[numChannels];
+                    Arrays.fill(gainValues, gainValue);
+                    sourceGainConfig = sourceGain.buildConfig(AudioGain.MODE_JOINT,
+                            sourceGain.channelMask(), gainValues, 0);
+                } else {
+                    Slog.w(TAG, "No audio source gain with MODE_JOINT support exists.");
+                }
+            }
+
+            AudioPortConfig sourceConfig = mAudioSource.activeConfig();
+            AudioPortConfig sinkConfig = mAudioSink.activeConfig();
+            AudioPatch[] audioPatchArray = new AudioPatch[] { mAudioPatch };
+            boolean shouldRecreateAudioPatch = false;
+            if (sinkConfig == null
+                    || (mDesiredSamplingRate != 0
+                            && sinkConfig.samplingRate() != mDesiredSamplingRate)
+                    || (mDesiredChannelMask != AudioFormat.CHANNEL_OUT_DEFAULT
+                            && sinkConfig.channelMask() != mDesiredChannelMask)
+                    || (mDesiredFormat != AudioFormat.ENCODING_DEFAULT
+                            && sinkConfig.format() != mDesiredFormat)) {
+                sinkConfig = mAudioSource.buildConfig(mDesiredSamplingRate, mDesiredChannelMask,
+                        mDesiredFormat, null);
+                shouldRecreateAudioPatch = true;
+            }
+            if (sourceConfig == null || sourceGainConfig != null) {
+                sourceConfig = mAudioSource.buildConfig(sinkConfig.samplingRate(),
+                        sinkConfig.channelMask(), sinkConfig.format(), sourceGainConfig);
+                shouldRecreateAudioPatch = true;
+            }
+            if (shouldRecreateAudioPatch) {
+                mCommittedVolume = mVolume;
+                mAudioManager.createAudioPatch(
+                        audioPatchArray,
+                        new AudioPortConfig[] { sourceConfig },
+                        new AudioPortConfig[] { sinkConfig });
+                mAudioPatch = audioPatchArray[0];
+            }
+        }
+
         @Override
-        public void setVolume(float volume) throws RemoteException {
+        public void setStreamVolume(float volume) throws RemoteException {
             synchronized (mImplLock) {
                 if (mReleased) {
                     throw new IllegalStateException("Device already released.");
                 }
+                mVolume = volume;
+                updateAudioPatchLocked();
             }
-            // TODO: Use AudioGain?
         }
 
         @Override
@@ -710,14 +825,47 @@
                 return result == TvInputHal.SUCCESS;
             }
         }
+
+        private void updateAudioSinkLocked() {
+            if (mInfo.getAudioType() == AudioManager.DEVICE_NONE) {
+                return;
+            }
+            if (mOverrideAudioType == AudioManager.DEVICE_NONE) {
+                mAudioSink = findAudioSinkFromAudioPolicy();
+            } else {
+                AudioDevicePort audioSink =
+                        findAudioDevicePort(mOverrideAudioType, mOverrideAudioAddress);
+                if (audioSink != null) {
+                    mAudioSink = audioSink;
+                }
+            }
+        }
+
+        @Override
+        public void overrideAudioSink(int audioType, String audioAddress, int samplingRate,
+                int channelMask, int format) {
+            synchronized (mImplLock) {
+                mOverrideAudioType = audioType;
+                mOverrideAudioAddress = audioAddress;
+                updateAudioSinkLocked();
+
+                mDesiredSamplingRate = samplingRate;
+                mDesiredChannelMask = channelMask;
+                mDesiredFormat = format;
+
+                if (mAudioPatch != null) {
+                    updateAudioPatchLocked();
+                }
+            }
+        }
     }
 
     interface Listener {
         public void onStateChanged(String inputId, int state);
         public void onHardwareDeviceAdded(TvInputHardwareInfo info);
         public void onHardwareDeviceRemoved(TvInputHardwareInfo info);
-        public void onHdmiCecDeviceAdded(HdmiCecDeviceInfo cecDevice);
-        public void onHdmiCecDeviceRemoved(HdmiCecDeviceInfo cecDevice);
+        public void onHdmiCecDeviceAdded(HdmiDeviceInfo cecDevice);
+        public void onHdmiCecDeviceRemoved(HdmiDeviceInfo cecDevice);
     }
 
     private class ListenerHandler extends Handler {
@@ -747,12 +895,12 @@
                     break;
                 }
                 case HDMI_CEC_DEVICE_ADDED: {
-                    HdmiCecDeviceInfo info = (HdmiCecDeviceInfo) msg.obj;
+                    HdmiDeviceInfo info = (HdmiDeviceInfo) msg.obj;
                     mListener.onHdmiCecDeviceAdded(info);
                     break;
                 }
                 case HDMI_CEC_DEVICE_REMOVED: {
-                    HdmiCecDeviceInfo info = (HdmiCecDeviceInfo) msg.obj;
+                    HdmiDeviceInfo info = (HdmiDeviceInfo) msg.obj;
                     mListener.onHdmiCecDeviceRemoved(info);
                     break;
                 }
@@ -788,7 +936,7 @@
 
     private final class HdmiDeviceEventListener extends IHdmiDeviceEventListener.Stub {
         @Override
-        public void onStatusChanged(HdmiCecDeviceInfo deviceInfo, boolean activated) {
+        public void onStatusChanged(HdmiDeviceInfo deviceInfo, boolean activated) {
             synchronized (mLock) {
                 if (activated) {
                     if (!mHdmiCecDeviceList.contains(deviceInfo)) {
@@ -818,7 +966,7 @@
 
     private final class HdmiInputChangeListener extends IHdmiInputChangeListener.Stub {
         @Override
-        public void onChanged(HdmiCecDeviceInfo device) throws RemoteException {
+        public void onChanged(HdmiDeviceInfo device) throws RemoteException {
             String inputId;
             synchronized (mLock) {
                 if (device.isCecDevice()) {
@@ -833,6 +981,7 @@
             if (inputId != null) {
                 Intent intent = new Intent(Intent.ACTION_VIEW);
                 intent.setData(TvContract.buildChannelUriForPassthroughTvInput(inputId));
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                 mContext.startActivity(intent);
             } else {
                 Slog.w(TAG, "onChanged: InputId cannot be found for :" + device);
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index e11b6a7..38e4997 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -38,7 +38,7 @@
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.graphics.Rect;
-import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.media.tv.ITvInputClient;
 import android.media.tv.ITvInputHardware;
 import android.media.tv.ITvInputHardwareCallback;
@@ -52,7 +52,6 @@
 import android.media.tv.TvContract;
 import android.media.tv.TvInputHardwareInfo;
 import android.media.tv.TvInputInfo;
-import android.media.tv.TvInputManager;
 import android.media.tv.TvInputService;
 import android.media.tv.TvStreamConfig;
 import android.media.tv.TvTrackInfo;
@@ -479,12 +478,13 @@
         // Set up a callback to send the session token.
         ITvInputSessionCallback callback = new ITvInputSessionCallback.Stub() {
             @Override
-            public void onSessionCreated(ITvInputSession session) {
+            public void onSessionCreated(ITvInputSession session, IBinder harewareSessionToken) {
                 if (DEBUG) {
                     Slog.d(TAG, "onSessionCreated(inputId=" + sessionState.mInfo.getId() + ")");
                 }
                 synchronized (mLock) {
                     sessionState.mSession = session;
+                    sessionState.mHardwareSessionToken = harewareSessionToken;
                     if (session == null) {
                         removeSessionStateLocked(sessionToken, userId);
                         sendSessionTokenToClientLocked(sessionState.mClient,
@@ -533,37 +533,35 @@
             }
 
             @Override
-            public void onTrackInfoChanged(List<TvTrackInfo> tracks) {
+            public void onTracksChanged(List<TvTrackInfo> tracks) {
                 synchronized (mLock) {
                     if (DEBUG) {
-                        Slog.d(TAG, "onTrackInfoChanged(" + tracks + ")");
+                        Slog.d(TAG, "onTracksChanged(" + tracks + ")");
                     }
                     if (sessionState.mSession == null || sessionState.mClient == null) {
                         return;
                     }
                     try {
-                        sessionState.mClient.onTrackInfoChanged(tracks,
-                                sessionState.mSeq);
+                        sessionState.mClient.onTracksChanged(tracks, sessionState.mSeq);
                     } catch (RemoteException e) {
-                        Slog.e(TAG, "error in onTrackInfoChanged");
+                        Slog.e(TAG, "error in onTracksChanged");
                     }
                 }
             }
 
             @Override
-            public void onTrackSelectionChanged(List<TvTrackInfo> selectedTracks) {
+            public void onTrackSelected(int type, String trackId) {
                 synchronized (mLock) {
                     if (DEBUG) {
-                        Slog.d(TAG, "onTrackSelectionChanged(" + selectedTracks + ")");
+                        Slog.d(TAG, "onTrackSelected(type=" + type + ", trackId=" + trackId + ")");
                     }
                     if (sessionState.mSession == null || sessionState.mClient == null) {
                         return;
                     }
                     try {
-                        sessionState.mClient.onTrackSelectionChanged(selectedTracks,
-                                sessionState.mSeq);
+                        sessionState.mClient.onTrackSelected(type, trackId, sessionState.mSeq);
                     } catch (RemoteException e) {
-                        Slog.e(TAG, "error in onTrackSelectionChanged");
+                        Slog.e(TAG, "error in onTrackSelected");
                     }
                 }
             }
@@ -637,6 +635,25 @@
             }
 
             @Override
+            public void onLayoutSurface(int left, int top, int right, int bottom) {
+                synchronized (mLock) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "onLayoutSurface (left=" + left + ", top=" + top
+                                + ", right=" + right + ", bottom=" + bottom + ",)");
+                    }
+                    if (sessionState.mSession == null || sessionState.mClient == null) {
+                        return;
+                    }
+                    try {
+                        sessionState.mClient.onLayoutSurface(left, top, right, bottom,
+                                sessionState.mSeq);
+                    } catch (RemoteException e) {
+                        Slog.e(TAG, "error in onLayoutSurface");
+                    }
+                }
+            }
+
+            @Override
             public void onSessionEvent(String eventType, Bundle eventArgs) {
                 synchronized (mLock) {
                     if (DEBUG) {
@@ -1109,8 +1126,14 @@
             try {
                 synchronized (mLock) {
                     try {
-                        getSessionLocked(sessionToken, callingUid, resolvedUserId).setSurface(
-                                surface);
+                        SessionState sessionState = getSessionStateLocked(sessionToken, callingUid,
+                                resolvedUserId);
+                        if (sessionState.mHardwareSessionToken == null) {
+                            getSessionLocked(sessionState).setSurface(surface);
+                        } else {
+                            getSessionLocked(sessionState.mHardwareSessionToken,
+                                    Process.SYSTEM_UID, resolvedUserId).setSurface(surface);
+                        }
                     } catch (RemoteException e) {
                         Slog.e(TAG, "error in setSurface", e);
                     }
@@ -1134,8 +1157,13 @@
             try {
                 synchronized (mLock) {
                     try {
-                        getSessionLocked(sessionToken, callingUid, resolvedUserId)
-                                .dispatchSurfaceChanged(format, width, height);
+                        SessionState sessionState = getSessionStateLocked(sessionToken, callingUid,
+                                resolvedUserId);
+                        getSessionLocked(sessionState).dispatchSurfaceChanged(format, width, height);
+                        if (sessionState.mHardwareSessionToken != null) {
+                            getSessionLocked(sessionState.mHardwareSessionToken, Process.SYSTEM_UID,
+                                    resolvedUserId).dispatchSurfaceChanged(format, width, height);
+                        }
                     } catch (RemoteException e) {
                         Slog.e(TAG, "error in dispatchSurfaceChanged", e);
                     }
@@ -1147,6 +1175,8 @@
 
         @Override
         public void setVolume(IBinder sessionToken, float volume, int userId) {
+            final float REMOTE_VOLUME_ON = 1.0f;
+            final float REMOTE_VOLUME_OFF = 0f;
             final int callingUid = Binder.getCallingUid();
             final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
                     userId, "setVolume");
@@ -1154,8 +1184,16 @@
             try {
                 synchronized (mLock) {
                     try {
-                        getSessionLocked(sessionToken, callingUid, resolvedUserId).setVolume(
-                                volume);
+                        SessionState sessionState = getSessionStateLocked(sessionToken, callingUid,
+                                resolvedUserId);
+                        getSessionLocked(sessionState).setVolume(volume);
+                        if (sessionState.mHardwareSessionToken != null) {
+                            // Here, we let the hardware session know only whether volume is on or
+                            // off to prevent that the volume is controlled in the both side.
+                            getSessionLocked(sessionState.mHardwareSessionToken,
+                                    Process.SYSTEM_UID, resolvedUserId).setVolume((volume > 0.0f)
+                                            ? REMOTE_VOLUME_ON : REMOTE_VOLUME_OFF);
+                        }
                     } catch (RemoteException e) {
                         Slog.e(TAG, "error in setVolume", e);
                     }
@@ -1266,7 +1304,7 @@
         }
 
         @Override
-        public void selectTrack(IBinder sessionToken, TvTrackInfo track, int userId) {
+        public void selectTrack(IBinder sessionToken, int type, String trackId, int userId) {
             final int callingUid = Binder.getCallingUid();
             final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
                     userId, "selectTrack");
@@ -1275,7 +1313,7 @@
                 synchronized (mLock) {
                     try {
                         getSessionLocked(sessionToken, callingUid, resolvedUserId).selectTrack(
-                                track);
+                                type, trackId);
                     } catch (RemoteException e) {
                         Slog.e(TAG, "error in selectTrack", e);
                     }
@@ -1286,26 +1324,6 @@
         }
 
         @Override
-        public void unselectTrack(IBinder sessionToken, TvTrackInfo track, int userId) {
-            final int callingUid = Binder.getCallingUid();
-            final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
-                    userId, "unselectTrack");
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                synchronized (mLock) {
-                    try {
-                        getSessionLocked(sessionToken, callingUid, resolvedUserId).unselectTrack(
-                                track);
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "error in unselectTrack", e);
-                    }
-                }
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-
-        @Override
         public void sendAppPrivateCommand(IBinder sessionToken, String command, Bundle data,
                 int userId) {
             final int callingUid = Binder.getCallingUid();
@@ -1479,13 +1497,24 @@
             final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
                     userId, "captureFrame");
             try {
-                final String wrappedInputId;
+                String hardwareInputId = null;
                 synchronized (mLock) {
                     UserState userState = getUserStateLocked(resolvedUserId);
-                    wrappedInputId = userState.wrappedInputMap.get(inputId);
+                    if (userState.inputMap.get(inputId) == null) {
+                        Slog.e(TAG, "Input not found for " + inputId);
+                        return false;
+                    }
+                    for (SessionState sessionState : userState.sessionStateMap.values()) {
+                        if (sessionState.mInfo.getId().equals(inputId)
+                                && sessionState.mHardwareSessionToken != null) {
+                            hardwareInputId = userState.sessionStateMap.get(
+                                    sessionState.mHardwareSessionToken).mInfo.getId();
+                            break;
+                        }
+                    }
                 }
                 return mTvInputHardwareManager.captureFrame(
-                        (wrappedInputId != null) ? wrappedInputId : inputId,
+                        (hardwareInputId != null) ? hardwareInputId : inputId,
                         surface, config, callingUid, resolvedUserId);
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -1493,6 +1522,34 @@
         }
 
         @Override
+        public boolean isSingleSessionActive(int userId) throws RemoteException {
+            final long identity = Binder.clearCallingIdentity();
+            final int callingUid = Binder.getCallingUid();
+            final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
+                    userId, "isSingleSessionActive");
+            try {
+                synchronized (mLock) {
+                    UserState userState = getUserStateLocked(resolvedUserId);
+                    if (userState.sessionStateMap.size() == 1) {
+                        return true;
+                    }
+                    else if (userState.sessionStateMap.size() == 2) {
+                        SessionState[] sessionStates = userState.sessionStateMap.values().toArray(
+                                new SessionState[0]);
+                        // Check if there is a wrapper input.
+                        if (sessionStates[0].mHardwareSessionToken != null
+                                || sessionStates[1].mHardwareSessionToken != null) {
+                            return true;
+                        }
+                    }
+                    return false;
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+
+        @Override
         @SuppressWarnings("resource")
         protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
             final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
@@ -1603,6 +1660,7 @@
                         pw.println("mSessionToken: " + session.mSessionToken);
                         pw.println("mSession: " + session.mSession);
                         pw.println("mLogUri: " + session.mLogUri);
+                        pw.println("mHardwareSessionToken: " + session.mHardwareSessionToken);
                         pw.decreaseIndent();
                     }
                     pw.decreaseIndent();
@@ -1692,9 +1750,6 @@
         private final Set<ITvInputManagerCallback> callbackSet =
                 new HashSet<ITvInputManagerCallback>();
 
-        // A mapping from the TV input id to wrapped input id.
-        private final Map<String, String> wrappedInputMap = new HashMap<String, String>();
-
         // The token of a "main" TV input session.
         private IBinder mainSessionToken = null;
 
@@ -1769,9 +1824,11 @@
         private final IBinder mSessionToken;
         private ITvInputSession mSession;
         private Uri mLogUri;
+        // Not null if this session represents an external device connected to a hardware TV input.
+        private IBinder mHardwareSessionToken;
 
-        private SessionState(IBinder sessionToken, TvInputInfo info, ITvInputClient client, int seq,
-                int callingUid, int userId) {
+        private SessionState(IBinder sessionToken, TvInputInfo info, ITvInputClient client,
+                int seq, int callingUid, int userId) {
             mSessionToken = sessionToken;
             mInfo = info;
             mClient = client;
@@ -1791,6 +1848,22 @@
                         Slog.e(TAG, "error in onSessionReleased", e);
                     }
                 }
+                // If there are any other sessions based on this session, they should be released.
+                UserState userState = getUserStateLocked(mUserId);
+                for (SessionState sessionState : userState.sessionStateMap.values()) {
+                    if (mSession != null && mSession == sessionState.mHardwareSessionToken) {
+                        try {
+                            sessionState.mSession.release();
+                        } catch (RemoteException e) {
+                            Slog.e(TAG, "error in release", e);
+                        }
+                        try {
+                            sessionState.mClient.onSessionReleased(sessionState.mSeq);
+                        } catch (RemoteException e) {
+                            Slog.e(TAG, "error in onSessionReleased", e);
+                        }
+                    }
+                }
                 removeSessionStateLocked(mSessionToken, mUserId);
             }
         }
@@ -1849,9 +1922,9 @@
                         }
                     }
 
-                    List<HdmiCecDeviceInfo> cecDeviceInfoList =
+                    List<HdmiDeviceInfo> cecDeviceInfoList =
                             mTvInputHardwareManager.getHdmiCecInputDeviceList();
-                    for (HdmiCecDeviceInfo cecDeviceInfo : cecDeviceInfoList) {
+                    for (HdmiDeviceInfo cecDeviceInfo : cecDeviceInfoList) {
                         try {
                             serviceState.mService.notifyHdmiCecDeviceAdded(cecDeviceInfo);
                         } catch (RemoteException e) {
@@ -1892,10 +1965,8 @@
 
                     for (TvInputState inputState : userState.inputMap.values()) {
                         if (inputState.mInfo.getComponent().equals(component)) {
-                            String inputId = inputState.mInfo.getId();
-                            notifyInputStateChangedLocked(userState, inputId,
+                            notifyInputStateChangedLocked(userState, inputState.mInfo.getId(),
                                     INPUT_STATE_DISCONNECTED, null);
-                            userState.wrappedInputMap.remove(inputId);
                         }
                     }
                     updateServiceConnectionLocked(mComponent, mUserId);
@@ -1974,27 +2045,6 @@
                 }
             }
         }
-
-        @Override
-        public void setWrappedInputId(String inputId, String wrappedInputId) {
-            synchronized (mLock) {
-                if (!hasInputIdLocked(inputId)) {
-                    return;
-                }
-                UserState userState = getUserStateLocked(mUserId);
-                userState.wrappedInputMap.put(inputId, wrappedInputId);
-            }
-        }
-
-        private boolean hasInputIdLocked(String inputId) {
-            ServiceState serviceState = getServiceStateLocked(mComponent, mUserId);
-            for (TvInputInfo inputInfo : serviceState.mInputList) {
-                if (inputInfo.getId().equals(inputId)) {
-                    return true;
-                }
-            }
-            return false;
-        }
     }
 
     private final class LogHandler extends Handler {
@@ -2182,7 +2232,7 @@
         }
 
         @Override
-        public void onHdmiCecDeviceAdded(HdmiCecDeviceInfo cecDeviceInfo) {
+        public void onHdmiCecDeviceAdded(HdmiDeviceInfo cecDeviceInfo) {
             synchronized (mLock) {
                 UserState userState = getUserStateLocked(mCurrentUserId);
                 // Broadcast the event to all hardware inputs.
@@ -2198,7 +2248,7 @@
         }
 
         @Override
-        public void onHdmiCecDeviceRemoved(HdmiCecDeviceInfo cecDeviceInfo) {
+        public void onHdmiCecDeviceRemoved(HdmiDeviceInfo cecDeviceInfo) {
             synchronized (mLock) {
                 UserState userState = getUserStateLocked(mCurrentUserId);
                 // Broadcast the event to all hardware inputs.
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
index 60724e7..d4c5f87 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
@@ -22,17 +22,20 @@
 import android.content.IntentFilter;
 import android.os.Binder;
 import android.os.Process;
-import android.util.Log;
+import android.util.Slog;
 import android.webkit.IWebViewUpdateService;
 import android.webkit.WebViewFactory;
 
+import com.android.server.SystemService;
+
 /**
  * Private service to wait for the updatable WebView to be ready for use.
  * @hide
  */
-public class WebViewUpdateService extends IWebViewUpdateService.Stub {
+public class WebViewUpdateService extends SystemService {
 
     private static final String TAG = "WebViewUpdateService";
+    private static final int WAIT_TIMEOUT_MS = 5000; // Same as KEY_DISPATCHING_TIMEOUT.
 
     private boolean mRelroReady32Bit = false;
     private boolean mRelroReady64Bit = false;
@@ -40,6 +43,11 @@
     private BroadcastReceiver mWebViewUpdatedReceiver;
 
     public WebViewUpdateService(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void onStart() {
         mWebViewUpdatedReceiver = new BroadcastReceiver() {
                 @Override
                 public void onReceive(Context context, Intent intent) {
@@ -52,57 +60,76 @@
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
         filter.addDataScheme("package");
-        context.registerReceiver(mWebViewUpdatedReceiver, filter);
-    }
+        getContext().registerReceiver(mWebViewUpdatedReceiver, filter);
 
-    /**
-     * The shared relro process calls this to notify us that it's done trying to create a relro
-     * file.
-     */
-    public void notifyRelroCreationCompleted(boolean is64Bit, boolean success) {
-        // Verify that the caller is the shared relro process.
-        if (Binder.getCallingUid() != Process.SHARED_RELRO_UID) {
-            return;
-        }
-
-        synchronized (this) {
-            if (is64Bit) {
-                mRelroReady64Bit = true;
-            } else {
-                mRelroReady32Bit = true;
-            }
-            this.notifyAll();
-        }
-    }
-
-    /**
-     * WebViewFactory calls this to block WebView loading until the relro file is created.
-     */
-    public void waitForRelroCreationCompleted(boolean is64Bit) {
-        synchronized (this) {
-            if (is64Bit) {
-                while (!mRelroReady64Bit) {
-                    try {
-                        this.wait();
-                    } catch (InterruptedException e) {}
-                }
-            } else {
-                while (!mRelroReady32Bit) {
-                    try {
-                        this.wait();
-                    } catch (InterruptedException e) {}
-                }
-            }
-        }
+        publishBinderService("webviewupdate", new BinderService());
     }
 
     private void onWebViewUpdateInstalled() {
-        Log.d(TAG, "WebView Package updated!");
+        Slog.d(TAG, "WebView Package updated!");
 
         synchronized (this) {
             mRelroReady32Bit = false;
             mRelroReady64Bit = false;
         }
-        WebViewFactory.prepareWebViewInSystemServer();
+        WebViewFactory.onWebViewUpdateInstalled();
     }
+
+    private class BinderService extends IWebViewUpdateService.Stub {
+
+        /**
+         * The shared relro process calls this to notify us that it's done trying to create a relro
+         * file. This method gets called even if the relro creation has failed or the process
+         * crashed.
+         */
+        @Override // Binder call
+        public void notifyRelroCreationCompleted(boolean is64Bit, boolean success) {
+            // Verify that the caller is either the shared relro process (nominal case) or the
+            // system server (only in the case the relro process crashes and we get here via the
+            // crashHandler).
+            if (Binder.getCallingUid() != Process.SHARED_RELRO_UID &&
+                    Binder.getCallingUid() != Process.SYSTEM_UID) {
+                return;
+            }
+
+            synchronized (WebViewUpdateService.this) {
+                if (is64Bit) {
+                    mRelroReady64Bit = true;
+                } else {
+                    mRelroReady32Bit = true;
+                }
+                WebViewUpdateService.this.notifyAll();
+            }
+        }
+
+        /**
+         * WebViewFactory calls this to block WebView loading until the relro file is created.
+         */
+        @Override // Binder call
+        public void waitForRelroCreationCompleted(boolean is64Bit) {
+            // The WebViewUpdateService depends on the prepareWebViewInSystemServer call, which
+            // happens later (during the PHASE_ACTIVITY_MANAGER_READY) in SystemServer.java. If
+            // another service there tries to bring up a WebView in the between, the wait below
+            // would deadlock without the check below.
+            if (Binder.getCallingPid() == Process.myPid()) {
+                throw new IllegalStateException("Cannot create a WebView from the SystemServer");
+            }
+
+            final long NS_PER_MS = 1000000;
+            final long timeoutTimeMs = System.nanoTime() / NS_PER_MS + WAIT_TIMEOUT_MS;
+            boolean relroReady = (is64Bit ? mRelroReady64Bit : mRelroReady32Bit);
+            synchronized (WebViewUpdateService.this) {
+                while (!relroReady) {
+                    final long timeNowMs = System.nanoTime() / NS_PER_MS;
+                    if (timeNowMs >= timeoutTimeMs) break;
+                    try {
+                        WebViewUpdateService.this.wait(timeoutTimeMs - timeNowMs);
+                    } catch (InterruptedException e) {}
+                    relroReady = (is64Bit ? mRelroReady64Bit : mRelroReady32Bit);
+                }
+            }
+            if (!relroReady) Slog.w(TAG, "creating relro file timed out");
+        }
+    }
+
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 80dfb91..304d2d4 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -619,6 +619,8 @@
         // Only set while traversing the default display based on its content.
         // Affects the behavior of mirroring on secondary displays.
         boolean mObscureApplicationContentOnSecondaryDisplays = false;
+
+        float mPreferredRefreshRate = 0;
     }
     final LayoutFields mInnerFields = new LayoutFields();
 
@@ -9091,6 +9093,10 @@
                     // Allow full screen keyguard presentation dialogs to be seen.
                     mInnerFields.mDisplayHasContent = true;
                 }
+                if (mInnerFields.mPreferredRefreshRate == 0
+                        && w.mAttrs.preferredRefreshRate != 0) {
+                    mInnerFields.mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
+                }
             }
         }
     }
@@ -9215,6 +9221,7 @@
 
                 // Reset for each display.
                 mInnerFields.mDisplayHasContent = false;
+                mInnerFields.mPreferredRefreshRate = 0;
 
                 int repeats = 0;
                 do {
@@ -9434,8 +9441,8 @@
                     updateResizingWindows(w);
                 }
 
-                mDisplayManagerInternal.setDisplayHasContent(displayId,
-                        mInnerFields.mDisplayHasContent,
+                mDisplayManagerInternal.setDisplayProperties(displayId,
+                        mInnerFields.mDisplayHasContent, mInnerFields.mPreferredRefreshRate,
                         true /* inTraversal, must call performTraversalInTrans... below */);
 
                 getDisplayContentLocked(displayId).stopDimmingIfNeeded();
@@ -11258,7 +11265,7 @@
                 final WindowList windows = getDefaultWindowListLocked();
                 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
                     final WindowState win = windows.get(winNdx);
-                    if (win.mHasSurface) {
+                    if (win.mHasSurface && win.mAppToken != null) {
                         win.mWinAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
                         // Force add to mResizingWindows.
                         win.mLastContentInsets.set(-1, -1, -1, -1);
diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp
index 5eb627b..d5abe0c 100644
--- a/services/core/jni/com_android_server_tv_TvInputHal.cpp
+++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp
@@ -400,18 +400,15 @@
         connection.mSurface->setSidebandStream(NULL);
         connection.mSurface.clear();
     }
+    if (connection.mThread != NULL) {
+        connection.mThread->shutdown();
+        connection.mThread.clear();
+    }
+    if (mDevice->close_stream(mDevice, deviceId, streamId) != 0) {
+        ALOGE("Couldn't remove stream");
+        return BAD_VALUE;
+    }
     if (connection.mSourceHandle != NULL) {
-        // Need to reset streams
-        if (mDevice->close_stream(mDevice, deviceId, streamId) != 0) {
-            ALOGE("Couldn't remove stream");
-            return BAD_VALUE;
-        }
-
-        // Clear everything
-        if (connection.mThread != NULL) {
-            connection.mThread->shutdown();
-            connection.mThread.clear();
-        }
         connection.mSourceHandle.clear();
     }
     return NO_ERROR;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 7f2018e..8e59844 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -18,14 +18,15 @@
 
 import static android.Manifest.permission.MANAGE_CA_CERTIFICATES;
 
+import android.app.admin.DevicePolicyManagerInternal;
 import com.android.internal.R;
-import com.android.internal.app.IAppOpsService;
 import com.android.internal.os.storage.ExternalStorageFormatter;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.JournaledFile;
 import com.android.internal.util.XmlUtils;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.org.conscrypt.TrustedCertificateStore;
+import com.android.server.LocalServices;
 import com.android.server.SystemService;
 
 import android.app.Activity;
@@ -46,7 +47,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
@@ -80,7 +80,6 @@
 import android.security.IKeyChainService;
 import android.security.KeyChain;
 import android.security.KeyChain.KeyChainConnection;
-import android.service.trust.TrustAgentService;
 import android.util.Log;
 import android.util.PrintWriterPrinter;
 import android.util.Printer;
@@ -111,13 +110,11 @@
 import java.security.cert.X509Certificate;
 import java.text.DateFormat;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
@@ -289,6 +286,9 @@
         private static final String ATTR_VALUE = "value";
         private static final String TAG_PASSWORD_QUALITY = "password-quality";
         private static final String TAG_POLICIES = "policies";
+        private static final String TAG_CROSS_PROFILE_WIDGET_PROVIDERS =
+                "cross-profile-widget-providers";
+        private static final String TAG_PROVIDER = "provider";
 
         final DeviceAdminInfo info;
 
@@ -346,6 +346,8 @@
         String globalProxyExclusionList = null;
         HashMap<String, List<String>> trustAgentFeatures = new HashMap<String, List<String>>();
 
+        List<String> crossProfileWidgetProviders;
+
         ActiveAdmin(DeviceAdminInfo _info) {
             info = _info;
         }
@@ -490,6 +492,17 @@
                 }
                 out.endTag(null, TAG_MANAGE_TRUST_AGENT_FEATURES);
             }
+            if (crossProfileWidgetProviders != null && !crossProfileWidgetProviders.isEmpty()) {
+                out.startTag(null, TAG_CROSS_PROFILE_WIDGET_PROVIDERS);
+                final int providerCount = crossProfileWidgetProviders.size();
+                for (int i = 0; i < providerCount; i++) {
+                    String provider = crossProfileWidgetProviders.get(i);
+                    out.startTag(null, TAG_PROVIDER);
+                    out.attribute(null, ATTR_VALUE, provider);
+                    out.endTag(null, TAG_PROVIDER);
+                }
+                out.endTag(null, TAG_CROSS_PROFILE_WIDGET_PROVIDERS);
+            }
         }
 
         void readFromXml(XmlPullParser parser)
@@ -571,6 +584,8 @@
                     accountTypesWithManagementDisabled = readDisableAccountInfo(parser, tag);
                 } else if (TAG_MANAGE_TRUST_AGENT_FEATURES.equals(tag)) {
                     trustAgentFeatures = getAllTrustAgentFeatures(parser, tag);
+                } else if (TAG_CROSS_PROFILE_WIDGET_PROVIDERS.equals(tag)) {
+                    crossProfileWidgetProviders = getCrossProfileWidgetProviders(parser, tag);
                 } else {
                     Slog.w(LOG_TAG, "Unknown admin tag: " + tag);
                 }
@@ -640,6 +655,30 @@
             return result;
         }
 
+        private List<String> getCrossProfileWidgetProviders(XmlPullParser parser, String tag)
+                throws XmlPullParserException, IOException  {
+            int outerDepthDAM = parser.getDepth();
+            int typeDAM;
+            ArrayList<String> result = null;
+            while ((typeDAM=parser.next()) != END_DOCUMENT
+                    && (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
+                if (typeDAM == END_TAG || typeDAM == TEXT) {
+                    continue;
+                }
+                String tagDAM = parser.getName();
+                if (TAG_PROVIDER.equals(tagDAM)) {
+                    final String provider = parser.getAttributeValue(null, ATTR_VALUE);
+                    if (result == null) {
+                        result = new ArrayList<>();
+                    }
+                    result.add(provider);
+                } else {
+                    Slog.w(LOG_TAG, "Unknown tag under " + tag +  ": " + tagDAM);
+                }
+            }
+            return result;
+        }
+
         void dump(String prefix, PrintWriter pw) {
             pw.print(prefix); pw.print("uid="); pw.println(getUid());
             pw.print(prefix); pw.println("policies:");
@@ -695,6 +734,8 @@
                     pw.println(disableScreenCapture);
             pw.print(prefix); pw.print("disabledKeyguardFeatures=");
                     pw.println(disabledKeyguardFeatures);
+            pw.print(prefix); pw.print("crossProfileWidgetProviders=");
+                    pw.println(crossProfileWidgetProviders);
         }
     }
 
@@ -752,6 +793,8 @@
         filter.addAction(Intent.ACTION_PACKAGE_ADDED);
         filter.addDataScheme("package");
         context.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
+
+        LocalServices.addService(DevicePolicyManagerInternal.class, new LocalService());
     }
 
     /**
@@ -1836,6 +1879,49 @@
         }
     }
 
+    @Override
+    public boolean addCrossProfileWidgetProvider(ComponentName admin, String packageName) {
+        ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(admin,
+                DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+        if (activeAdmin.crossProfileWidgetProviders == null) {
+            activeAdmin.crossProfileWidgetProviders = new ArrayList<>();
+        }
+        if (activeAdmin.crossProfileWidgetProviders.add(packageName)) {
+            saveSettingsLocked(UserHandle.getCallingUserId());
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean removeCrossProfileWidgetProvider(ComponentName admin, String packageName) {
+        ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(admin,
+                DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+        if (activeAdmin.crossProfileWidgetProviders == null) {
+            return false;
+        }
+        if (activeAdmin.crossProfileWidgetProviders.remove(packageName)) {
+            saveSettingsLocked(UserHandle.getCallingUserId());
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public List<String> getCrossProfileWidgetProviders(ComponentName admin) {
+        ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(admin,
+                DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+        if (activeAdmin.crossProfileWidgetProviders == null
+                || activeAdmin.crossProfileWidgetProviders.isEmpty()) {
+            return null;
+        }
+        if (Binder.getCallingUid() == Process.myUid()) {
+            return new ArrayList<>(activeAdmin.crossProfileWidgetProviders);
+        } else {
+            return activeAdmin.crossProfileWidgetProviders;
+        }
+    }
+
     /**
      * Return a single admin's expiration date/time, or the min (soonest) for all admins.
      * Returns 0 if not configured.
@@ -4502,4 +4588,28 @@
             }
         }
     }
+
+    private final class LocalService extends DevicePolicyManagerInternal {
+        @Override
+        public List<String> getCrossProfileWidgetProviders(int profileId) {
+            ComponentName ownerComponent = mDeviceOwner.getProfileOwnerComponent(profileId);
+            if (ownerComponent == null) {
+                return Collections.emptyList();
+            }
+
+            DevicePolicyData policy = getUserData(profileId);
+            ActiveAdmin admin = policy.mAdminMap.get(ownerComponent);
+
+            if (admin == null) {
+                return Collections.emptyList();
+            }
+
+            if (admin.crossProfileWidgetProviders == null
+                    || admin.crossProfileWidgetProviders.isEmpty()) {
+                return Collections.emptyList();
+            }
+
+            return admin.crossProfileWidgetProviders;
+        }
+    }
 }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index d955354..e8d6773 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -376,6 +376,9 @@
         mSystemServiceManager.startService(UsageStatsService.class);
         mActivityManagerService.setUsageStatsManager(
                 LocalServices.getService(UsageStatsManagerInternal.class));
+
+        // Tracks whether the updatable WebView is in a ready state and watches for update installs.
+        mSystemServiceManager.startService(WebViewUpdateService.class);
     }
 
     /**
@@ -422,12 +425,6 @@
             Slog.i(TAG, "Reading configuration...");
             SystemConfig.getInstance();
 
-            Slog.i(TAG, "WebView Update Service");
-            ServiceManager.addService("webviewupdate", new WebViewUpdateService(context));
-
-            Slog.i(TAG, "WebViewFactory preparation");
-            WebViewFactory.prepareWebViewInSystemServer();
-
             Slog.i(TAG, "Scheduling Policy");
             ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());
 
@@ -1080,6 +1077,10 @@
                 } catch (Throwable e) {
                     reportWtf("observing native crashes", e);
                 }
+
+                Slog.i(TAG, "WebViewFactory preparation");
+                WebViewFactory.prepareWebViewInSystemServer();
+
                 try {
                     startSystemUi(context);
                 } catch (Throwable e) {
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index 0575a5e..7400dde 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -734,7 +734,7 @@
             }
             if (mContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL)
                     != PackageManager.PERMISSION_GRANTED
-                ||  mContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS)
+                &&  mContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS)
                     != PackageManager.PERMISSION_GRANTED) {
                 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
                     return callingUserId;
@@ -746,8 +746,7 @@
             if (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) {
                 return mCurrentUserId;
             }
-            throw new IllegalArgumentException("Calling user can be changed to only "
-                    + "UserHandle.USER_CURRENT or UserHandle.USER_CURRENT_OR_SELF.");
+            return userId;
         }
 
         private String resolveCallingPackageNameEnforcingSecurity(String packageName) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java
index 8913eb9..b4c221f 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java
@@ -195,7 +195,8 @@
                     Keyphrase[] keyphrases = new Keyphrase[1];
                     keyphrases[0] = new Keyphrase(
                             keyphraseId, recognitionModes, locale, text, users);
-                    return new KeyphraseSoundModel(UUID.fromString(modelUuid), data, keyphrases);
+                    return new KeyphraseSoundModel(UUID.fromString(modelUuid),
+                            null /* FIXME use vendor UUID */, data, keyphrases);
                 }
                 Slog.w(TAG, "No SoundModel available for the given keyphrase");
             } finally {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
index 0eac1c4..fd36bfc 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
@@ -25,6 +25,7 @@
 import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
 import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
 import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent;
+import android.hardware.soundtrigger.SoundTrigger.SoundModelEvent;
 import android.hardware.soundtrigger.SoundTriggerModule;
 import android.os.RemoteException;
 import android.util.Slog;
@@ -65,6 +66,8 @@
 
     private int mCurrentSoundModelHandle = INVALID_SOUND_MODEL_HANDLE;
     private UUID mCurrentSoundModelUuid = null;
+    // FIXME: Ideally this should not be stored if allowMultipleTriggers happens at a lower layer.
+    private RecognitionConfig mRecognitionConfig = null;
 
     SoundTriggerHelper() {
         ArrayList <ModuleProperties> modules = new ArrayList<>();
@@ -174,6 +177,7 @@
         // Everything went well!
         mCurrentSoundModelHandle = soundModelHandle;
         mCurrentSoundModelUuid = soundModel.uuid;
+        mRecognitionConfig = recognitionConfig;
         // Register the new listener. This replaces the old one.
         // There can only be a maximum of one active listener for a keyphrase
         // at any given time.
@@ -221,12 +225,12 @@
             int status = mModule.stopRecognition(mCurrentSoundModelHandle);
             if (status != SoundTrigger.STATUS_OK) {
                 Slog.w(TAG, "stopRecognition call failed with " + status);
-                return STATUS_ERROR;
+                return status;
             }
             status = mModule.unloadSoundModel(mCurrentSoundModelHandle);
             if (status != SoundTrigger.STATUS_OK) {
                 Slog.w(TAG, "unloadSoundModel call failed with " + status);
-                return STATUS_ERROR;
+                return status;
             }
 
             mCurrentSoundModelHandle = INVALID_SOUND_MODEL_HANDLE;
@@ -237,6 +241,30 @@
         }
     }
 
+    synchronized void stopAllRecognitions() {
+        if (moduleProperties == null || mModule == null) {
+            return;
+        }
+
+        if (mCurrentSoundModelHandle == INVALID_SOUND_MODEL_HANDLE) {
+            return;
+        }
+
+        int status = mModule.stopRecognition(mCurrentSoundModelHandle);
+        if (status != SoundTrigger.STATUS_OK) {
+            Slog.w(TAG, "stopRecognition call failed with " + status);
+        }
+        status = mModule.unloadSoundModel(mCurrentSoundModelHandle);
+        if (status != SoundTrigger.STATUS_OK) {
+            Slog.w(TAG, "unloadSoundModel call failed with " + status);
+        }
+
+        mCurrentSoundModelHandle = INVALID_SOUND_MODEL_HANDLE;
+        mCurrentSoundModelUuid = null;
+
+        mActiveListeners.clear();
+    }
+
     //---- SoundTrigger.StatusListener methods
     @Override
     public void onRecognition(RecognitionEvent event) {
@@ -284,6 +312,17 @@
                             Slog.w(TAG, "received onRecognition event without any listener for it");
                             return;
                         }
+
+                        // FIXME: Remove this block if the lower layer supports multiple triggers.
+                        if (mRecognitionConfig != null
+                                && mRecognitionConfig.allowMultipleTriggers) {
+                            int status = mModule.startRecognition(
+                                    mCurrentSoundModelHandle, mRecognitionConfig);
+                            if (status != STATUS_OK) {
+                                Slog.w(TAG, "Error in restarting recognition after a trigger");
+                                listener.onError(status);
+                            }
+                        }
                     }
                 } catch (RemoteException e) {
                     Slog.w(TAG, "RemoteException in onDetectionStopped");
@@ -292,6 +331,23 @@
         }
     }
 
+    public void onSoundModelUpdate(SoundModelEvent event) {
+        if (event == null) {
+            Slog.w(TAG, "Invalid sound model event!");
+            return;
+        }
+
+        if (DBG) Slog.d(TAG, "onSoundModelUpdate: " + event);
+
+        //TODO: implement sound model update
+    }
+
+    public void onServiceStateChange(int state) {
+        if (DBG) Slog.d(TAG, "onServiceStateChange, state: " + state);
+
+        //TODO: implement service state update
+    }
+
     @Override
     public void onServiceDied() {
         synchronized (this) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index a3d578a..75d41aa 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -49,9 +49,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.List;
-import java.util.UUID;
-
 
 /**
  * SystemService that publishes an IVoiceInteractionManagerService.
@@ -151,6 +148,7 @@
                 }
                 if (force || mImpl == null || mImpl.mUser != mCurUser
                         || !mImpl.mComponent.equals(serviceComponent)) {
+                    mSoundTriggerHelper.stopAllRecognitions();
                     if (mImpl != null) {
                         mImpl.shutdownLocked();
                     }
diff --git a/telecomm/java/android/telecomm/Call.java b/telecomm/java/android/telecomm/Call.java
index 838f221..4e9e604 100644
--- a/telecomm/java/android/telecomm/Call.java
+++ b/telecomm/java/android/telecomm/Call.java
@@ -24,6 +24,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
 /**
@@ -74,7 +75,7 @@
         private final String mCallerDisplayName;
         private final int mCallerDisplayNamePresentation;
         private final PhoneAccountHandle mAccountHandle;
-        private final int mCapabilities;
+        private final int mCallCapabilities;
         private final int mDisconnectCauseCode;
         private final String mDisconnectCauseMsg;
         private final long mConnectTimeMillis;
@@ -125,8 +126,8 @@
          * @return A bitmask of the capabilities of the {@code Call}, as defined in
          *         {@link CallCapabilities}.
          */
-        public int getCapabilities() {
-            return mCapabilities;
+        public int getCallCapabilities() {
+            return mCallCapabilities;
         }
 
         /**
@@ -162,14 +163,15 @@
         }
 
         /**
-         * @return Returns the video state of the {@code Call}.
+         * @return The video state of the {@code Call}.
          */
         public int getVideoState() {
             return mVideoState;
         }
 
-        /*
-         * @return The current {@link android.telecomm.StatusHints}, or null if none has been set.
+        /**
+         * @return The current {@link android.telecomm.StatusHints}, or {@code null} if none
+         * have been set.
          */
         public StatusHints getStatusHints() {
             return mStatusHints;
@@ -186,7 +188,7 @@
                         Objects.equals(mCallerDisplayNamePresentation,
                                 d.mCallerDisplayNamePresentation) &&
                         Objects.equals(mAccountHandle, d.mAccountHandle) &&
-                        Objects.equals(mCapabilities, d.mCapabilities) &&
+                        Objects.equals(mCallCapabilities, d.mCallCapabilities) &&
                         Objects.equals(mDisconnectCauseCode, d.mDisconnectCauseCode) &&
                         Objects.equals(mDisconnectCauseMsg, d.mDisconnectCauseMsg) &&
                         Objects.equals(mConnectTimeMillis, d.mConnectTimeMillis) &&
@@ -205,7 +207,7 @@
                     Objects.hashCode(mCallerDisplayName) +
                     Objects.hashCode(mCallerDisplayNamePresentation) +
                     Objects.hashCode(mAccountHandle) +
-                    Objects.hashCode(mCapabilities) +
+                    Objects.hashCode(mCallCapabilities) +
                     Objects.hashCode(mDisconnectCauseCode) +
                     Objects.hashCode(mDisconnectCauseMsg) +
                     Objects.hashCode(mConnectTimeMillis) +
@@ -233,7 +235,7 @@
             mCallerDisplayName = callerDisplayName;
             mCallerDisplayNamePresentation = callerDisplayNamePresentation;
             mAccountHandle = accountHandle;
-            mCapabilities = capabilities;
+            mCallCapabilities = capabilities;
             mDisconnectCauseCode = disconnectCauseCode;
             mDisconnectCauseMsg = disconnectCauseMsg;
             mConnectTimeMillis = connectTimeMillis;
@@ -289,15 +291,6 @@
         public void onCannedTextResponsesLoaded(Call call, List<String> cannedTextResponses) {}
 
         /**
-         * Invoked when the outgoing {@code Call} has finished dialing but is sending DTMF signals
-         * that were embedded into the outgoing number.
-         *
-         * @param call The {@code Call} invoking this method.
-         * @param remainingPostDialSequence The post-dial characters that remain to be sent.
-         */
-        public void onPostDial(Call call, String remainingPostDialSequence) {}
-
-        /**
          * Invoked when the post-dial sequence in the outgoing {@code Call} has reached a pause
          * character. This causes the post-dial signals to stop pending user confirmation. An
          * implementation should present this choice to the user and invoke
@@ -314,7 +307,6 @@
          * @param call The {@code Call} invoking this method.
          * @param videoCall The {@code Call.VideoCall} associated with the {@code Call}.
          */
-
         public void onVideoCallChanged(Call call, InCallService.VideoCall videoCall) {}
 
         /**
@@ -335,20 +327,34 @@
          * @param call The {@code Call} being destroyed.
          */
         public void onCallDestroyed(Call call) {}
+
+        /**
+         * Invoked upon changes to the set of {@code Call}s with which this {@code Call} can be
+         * conferenced.
+         *
+         * @param call The {@code Call} being updated.
+         * @param conferenceableCalls The {@code Call}s with which this {@code Call} can be
+         *          conferenced.
+         */
+        public void onConferenceableCallsChanged(Call call, List<Call> conferenceableCalls) {}
     }
 
     private final Phone mPhone;
     private final String mTelecommCallId;
     private final InCallAdapter mInCallAdapter;
-    private Call mParent = null;
-    private int mState;
     private final List<Call> mChildren = new ArrayList<>();
     private final List<Call> mUnmodifiableChildren = Collections.unmodifiableList(mChildren);
+    private final List<Listener> mListeners = new ArrayList<>();
+    private final List<Call> mConferenceableCalls = new ArrayList<>();
+    private final List<Call> mUnmodifiableConferenceableCalls =
+            Collections.unmodifiableList(mConferenceableCalls);
+
+    private Call mParent = null;
+    private int mState;
     private List<String> mCannedTextResponses = null;
     private String mRemainingPostDialSequence;
     private InCallService.VideoCall mVideoCall;
     private Details mDetails;
-    private final List<Listener> mListeners = new ArrayList<>();
 
     /**
      * Obtains the post-dial sequence remaining to be emitted by this {@code Call}, if any.
@@ -427,8 +433,6 @@
      *
      * A post-dial DTMF string is a string of digits entered after a phone number, when dialed,
      * that are immediately sent as DTMF tones to the recipient as soon as the connection is made.
-     * While these tones are playing, this {@code Call} will notify listeners via
-     * {@link Listener#onPostDial(Call, String)}.
      *
      * If the DTMF string contains a {@link TelecommManager#DTMF_CHARACTER_PAUSE} symbol, this
      * {@code Call} will temporarily pause playing the tones for a pre-defined period of time.
@@ -466,9 +470,13 @@
 
     /**
      * Instructs this {@code Call} to enter a conference.
+     *
+     * @param callToConferenceWith The other call with which to conference.
      */
-    public void conference() {
-        mInCallAdapter.conference(mTelecommCallId);
+    public void conference(Call callToConferenceWith) {
+        if (callToConferenceWith != null) {
+            mInCallAdapter.conference(mTelecommCallId, callToConferenceWith.mTelecommCallId);
+        }
     }
 
     /**
@@ -508,6 +516,15 @@
     }
 
     /**
+     * Returns the list of {@code Call}s with which this {@code Call} is allowed to conference.
+     *
+     * @return The list of conferenceable {@code Call}s.
+     */
+    public List<Call> getConferenceableCalls() {
+        return mUnmodifiableConferenceableCalls;
+    }
+
+    /**
      * Obtains the state of this {@code Call}.
      *
      * @return A state value, chosen from the {@code STATE_*} constants.
@@ -579,9 +596,8 @@
     }
 
     /** {@hide} */
-    final void internalUpdate(ParcelableCall parcelableCall) {
+    final void internalUpdate(ParcelableCall parcelableCall, Map<String, Call> callIdMap) {
         // First, we update the internal state as far as possible before firing any updates.
-
         Details details = new Details(
                 parcelableCall.getHandle(),
                 parcelableCall.getHandlePresentation(),
@@ -630,6 +646,20 @@
             }
         }
 
+        List<String> conferenceableCallIds = parcelableCall.getConferenceableCallIds();
+        List<Call> conferenceableCalls = new ArrayList<Call>(conferenceableCallIds.size());
+        for (String otherId : conferenceableCallIds) {
+            if (callIdMap.containsKey(otherId)) {
+                conferenceableCalls.add(callIdMap.get(otherId));
+            }
+        }
+
+        if (!Objects.equals(mConferenceableCalls, conferenceableCalls)) {
+            mConferenceableCalls.clear();
+            mConferenceableCalls.addAll(conferenceableCalls);
+            fireConferenceableCallsChanged();
+        }
+
         // Now we fire updates, ensuring that any client who listens to any of these notifications
         // gets the most up-to-date state.
 
@@ -657,12 +687,6 @@
     }
 
     /** {@hide} */
-    final void internalSetPostDial(String remaining) {
-        mRemainingPostDialSequence = remaining;
-        firePostDial(mRemainingPostDialSequence);
-    }
-
-    /** {@hide} */
     final void internalSetPostDialWait(String remaining) {
         mRemainingPostDialSequence = remaining;
         firePostDialWait(mRemainingPostDialSequence);
@@ -715,13 +739,6 @@
         }
     }
 
-    private void firePostDial(String remainingPostDialSequence) {
-        Listener[] listeners = mListeners.toArray(new Listener[mListeners.size()]);
-        for (int i = 0; i < listeners.length; i++) {
-            listeners[i].onPostDial(this, remainingPostDialSequence);
-        }
-    }
-
     private void firePostDialWait(String remainingPostDialSequence) {
         Listener[] listeners = mListeners.toArray(new Listener[mListeners.size()]);
         for (int i = 0; i < listeners.length; i++) {
@@ -743,6 +760,13 @@
         }
     }
 
+    private void fireConferenceableCallsChanged() {
+        Listener[] listeners = mListeners.toArray(new Listener[mListeners.size()]);
+        for (int i = 0; i < listeners.length; i++) {
+            listeners[i].onConferenceableCallsChanged(this, mUnmodifiableConferenceableCalls);
+        }
+    }
+
     private int stateFromParcelableCallState(CallState parcelableCallState) {
         switch (parcelableCallState) {
             case NEW:
@@ -766,4 +790,4 @@
                 return STATE_NEW;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/telecomm/java/android/telecomm/Connection.java b/telecomm/java/android/telecomm/Connection.java
index 8845821..d347aad 100644
--- a/telecomm/java/android/telecomm/Connection.java
+++ b/telecomm/java/android/telecomm/Connection.java
@@ -21,9 +21,9 @@
 import android.os.Bundle;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
 
 /**
  * Represents a connection to a remote endpoint that carries voice traffic.
@@ -49,7 +49,8 @@
         public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {}
         public void onStatusHintsChanged(Connection c, StatusHints statusHints) {}
         public void onStartActivityFromInCall(Connection c, PendingIntent intent) {}
-        public void onFailed(Connection c, int code, String msg) {}
+        public void onConferenceableConnectionsChanged(
+                Connection c, List<Connection> conferenceableConnections) {}
     }
 
     public final class State {
@@ -67,8 +68,18 @@
 
     }
 
-    private final Set<Listener> mListeners = new HashSet<>();
+    private final Listener mConnectionDeathListener = new Listener() {
+        @Override
+        public void onDestroyed(Connection c) {
+            if (mConferenceableConnections.remove(c)) {
+                fireOnConferenceableConnectionsChanged();
+            }
+        }
+    };
+
+    private final Set<Listener> mListeners = new CopyOnWriteArraySet<>();
     private final List<Connection> mChildConnections = new ArrayList<>();
+    private final List<Connection> mConferenceableConnections = new ArrayList<>();
 
     private int mState = State.NEW;
     private CallAudioState mCallAudioState;
@@ -485,7 +496,7 @@
     }
 
     /**
-     * TODO(santoscordon): Needs documentation.
+     * Tears down the Connection object.
      */
     public final void destroy() {
         // It is possible that onDestroy() will trigger the listener to remove itself which will
@@ -534,6 +545,24 @@
     }
 
     /**
+     * Sets the connections with which this connection can be conferenced.
+     *
+     * @param conferenceableConnections The set of connections this connection can conference with.
+     */
+    public final void setConferenceableConnections(List<Connection> conferenceableConnections) {
+        clearConferenceableList();
+        for (Connection c : conferenceableConnections) {
+            // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
+            // small amount of items here.
+            if (!mConferenceableConnections.contains(c)) {
+                c.addConnectionListener(mConnectionDeathListener);
+                mConferenceableConnections.add(c);
+            }
+        }
+        fireOnConferenceableConnectionsChanged();
+    }
+
+    /**
      * Launches an activity for this connection on top of the in-call UI.
      *
      * @param intent The intent to use to start the activity.
@@ -580,7 +609,7 @@
     public void onDisconnect() {}
 
     /**
-     * Notifies this Connection of a request to disconnect.
+     * Notifies this Connection of a request to separate from its parent conference.
      */
     public void onSeparate() {}
 
@@ -634,6 +663,16 @@
      */
     public void onPhoneAccountClicked() {}
 
+    /**
+     * Merge this connection and the specified connection into a conference call.  Once the
+     * connections are merged, the calls should be added to the an existing or new
+     * {@code Conference} instance. For new {@code Conference} instances, use
+     * {@code ConnectionService#addConference}.
+     *
+     * @param otherConnection The connection with which this connection should be conferenced.
+     */
+    public void onConferenceWith(Connection otherConnection) {}
+
     private void addChild(Connection connection) {
         Log.d(this, "adding child %s", connection);
         mChildConnections.add(connection);
@@ -693,4 +732,17 @@
     public static Connection getCanceledConnection() {
         return CANCELED_CONNECTION;
     }
+
+    private final void  fireOnConferenceableConnectionsChanged() {
+        for (Listener l : mListeners) {
+            l.onConferenceableConnectionsChanged(this, mConferenceableConnections);
+        }
+    }
+
+    private final void clearConferenceableList() {
+        for (Connection c : mConferenceableConnections) {
+            c.removeConnectionListener(mConnectionDeathListener);
+        }
+        mConferenceableConnections.clear();
+    }
 }
diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java
index 1484021..fddc9b0 100644
--- a/telecomm/java/android/telecomm/ConnectionService.java
+++ b/telecomm/java/android/telecomm/ConnectionService.java
@@ -39,10 +39,13 @@
 import com.android.internal.telecomm.IVideoCallProvider;
 import com.android.internal.telecomm.RemoteServiceCallback;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * A {@link android.app.Service} that provides telephone connections to processes running on an
@@ -57,7 +60,6 @@
 
     // Flag controlling whether PII is emitted into the logs
     private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
-    private static final Connection NULL_CONNECTION = new Connection() {};
 
     private static final int MSG_ADD_CALL_SERVICE_ADAPTER = 1;
     private static final int MSG_CREATE_CONNECTION = 2;
@@ -76,11 +78,14 @@
     private static final int MSG_ON_POST_DIAL_CONTINUE = 15;
     private static final int MSG_ON_PHONE_ACCOUNT_CLICKED = 16;
 
+    private static Connection sNullConnection;
+
     private final Map<String, Connection> mConnectionById = new HashMap<>();
     private final Map<Connection, String> mIdByConnection = new HashMap<>();
     private final RemoteConnectionManager mRemoteConnectionManager = new RemoteConnectionManager();
 
     private boolean mAreAccountsInitialized = false;
+    private final List<Runnable> mPreInitializationConnectionRequests = new ArrayList<>();
     private final ConnectionServiceAdapter mAdapter = new ConnectionServiceAdapter();
 
     /**
@@ -226,11 +231,23 @@
                 case MSG_CREATE_CONNECTION: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        PhoneAccountHandle connectionManagerPhoneAccount =
+                        final PhoneAccountHandle connectionManagerPhoneAccount =
                                 (PhoneAccountHandle) args.arg1;
-                        ConnectionRequest request = (ConnectionRequest) args.arg2;
-                        boolean isIncoming = args.argi1 == 1;
-                        createConnection(connectionManagerPhoneAccount, request, isIncoming);
+                        final ConnectionRequest request = (ConnectionRequest) args.arg2;
+                        final boolean isIncoming = args.argi1 == 1;
+                        if (!mAreAccountsInitialized) {
+                            mPreInitializationConnectionRequests.add(new Runnable() {
+                                @Override
+                                public void run() {
+                                    createConnection(
+                                            connectionManagerPhoneAccount,
+                                            request,
+                                            isIncoming);
+                                }
+                            });
+                        } else {
+                            createConnection(connectionManagerPhoneAccount, request, isIncoming);
+                        }
                     } finally {
                         args.recycle();
                     }
@@ -397,10 +414,11 @@
         @Override
         public void onCallCapabilitiesChanged(Connection c, int callCapabilities) {
             String id = mIdByConnection.get(c);
+            Log.d(this, "call capabilities: parcelableconnection: %s",
+                    CallCapabilities.toString(callCapabilities));
             mAdapter.setCallCapabilities(id, callCapabilities);
         }
 
-        /** ${inheritDoc} */
         @Override
         public void onParentConnectionChanged(Connection c, Connection parent) {
             String id = mIdByConnection.get(c);
@@ -431,6 +449,20 @@
             String id = mIdByConnection.get(c);
             mAdapter.startActivityFromInCall(id, intent);
         }
+
+        @Override
+        public void onConferenceableConnectionsChanged(
+                Connection connection, List<Connection> conferenceableConnections) {
+            String id = mIdByConnection.get(connection);
+            List<String> conferenceableCallIds = new ArrayList<>(conferenceableConnections.size());
+            for (Connection c : conferenceableConnections) {
+                if (mIdByConnection.containsKey(c)) {
+                    conferenceableCallIds.add(mIdByConnection.get(c));
+                }
+            }
+            Collections.sort(conferenceableCallIds);
+            mAdapter.setConferenceableConnections(id, conferenceableCallIds);
+        }
     };
 
     /** {@inheritDoc} */
@@ -505,6 +537,14 @@
 
     private void connectionCreated(ConnectionRequest request, Connection connection) {
         addConnection(request.getCallId(), connection);
+        Uri handle = connection.getHandle();
+        String number = handle == null ? "null" : handle.getSchemeSpecificPart();
+        Log.v(this, "connectionCreated, parcelableconnection: %s, %d, %s",
+                toLogSafePhoneNumber(number),
+                connection.getState(),
+                CallCapabilities.toString(connection.getCallCapabilities()));
+
+
         mAdapter.handleCreateConnectionSuccessful(
                 request,
                 new ParcelableConnection(
@@ -569,7 +609,7 @@
         Log.d(this, "conference %s, %s", conferenceCallId, callId);
 
         Connection connection = findConnectionForAction(callId, "conference");
-        if (connection == NULL_CONNECTION) {
+        if (connection == getNullConnection()) {
             Log.w(this, "Connection missing in conference request %s.", callId);
             return;
         }
@@ -602,7 +642,7 @@
         Log.d(this, "splitFromConference(%s)", callId);
 
         Connection connection = findConnectionForAction(callId, "splitFromConference");
-        if (connection == NULL_CONNECTION) {
+        if (connection == getNullConnection()) {
             Log.w(this, "Connection missing in conference request %s.", callId);
             return;
         }
@@ -643,7 +683,7 @@
                                     componentNames.get(i),
                                     IConnectionService.Stub.asInterface(services.get(i)));
                         }
-                        mAreAccountsInitialized = true;
+                        onAccountsInitialized();
                         Log.d(this, "remote connection services found: " + services);
                     }
                 });
@@ -803,6 +843,14 @@
         return builder.toString();
     }
 
+    private void onAccountsInitialized() {
+        mAreAccountsInitialized = true;
+        for (Runnable r : mPreInitializationConnectionRequests) {
+            r.run();
+        }
+        mPreInitializationConnectionRequests.clear();
+    }
+
     private void addConnection(String callId, Connection connection) {
         mConnectionById.put(callId, connection);
         mIdByConnection.put(connection, callId);
@@ -822,9 +870,21 @@
             return mConnectionById.get(callId);
         }
         Log.w(this, "%s - Cannot find Connection %s", action, callId);
-        return NULL_CONNECTION;
+        return getNullConnection();
     }
 
+    private final static synchronized Connection getNullConnection() {
+        if (sNullConnection == null) {
+            sNullConnection = new Connection() {};
+        }
+        return sNullConnection;
+    }
+
+    /**
+     * Abstraction for a class which provides video call functionality. This class contains no base
+     * implementation for its methods. It is expected that subclasses will override these
+     * functions to provide the desired behavior if it is supported.
+     */
     public static abstract class VideoCallProvider {
         private static final int MSG_SET_VIDEO_CALL_LISTENER = 1;
         private static final int MSG_SET_CAMERA = 2;
@@ -957,38 +1017,48 @@
          *
          * @param cameraId The id of the camera.
          */
-        public abstract void onSetCamera(String cameraId);
+        public void onSetCamera(String cameraId) {
+            // To be implemented by subclass.
+        }
 
         /**
          * Sets the surface to be used for displaying a preview of what the user's camera is
-         * currently capturing.  When video transmission is enabled, this is the video signal which is
-         * sent to the remote device.
+         * currently capturing.  When video transmission is enabled, this is the video signal which
+         * is sent to the remote device.
          *
          * @param surface The surface.
          */
-        public abstract void onSetPreviewSurface(Surface surface);
+        public void onSetPreviewSurface(Surface surface) {
+            // To be implemented by subclass.
+        }
 
         /**
          * Sets the surface to be used for displaying the video received from the remote device.
          *
          * @param surface The surface.
          */
-        public abstract void onSetDisplaySurface(Surface surface);
+        public void onSetDisplaySurface(Surface surface) {
+            // To be implemented by subclass.
+        }
 
         /**
-         * Sets the device orientation, in degrees.  Assumes that a standard portrait orientation of the
-         * device is 0 degrees.
+         * Sets the device orientation, in degrees.  Assumes that a standard portrait orientation of
+         * the device is 0 degrees.
          *
          * @param rotation The device orientation, in degrees.
          */
-        public abstract void onSetDeviceOrientation(int rotation);
+        public void onSetDeviceOrientation(int rotation) {
+            // To be implemented by subclass.
+        }
 
         /**
          * Sets camera zoom ratio.
          *
          * @param value The camera zoom ratio.
          */
-        public abstract void onSetZoom(float value);
+        public void onSetZoom(float value) {
+            // To be implemented by subclass.
+        }
 
         /**
          * Issues a request to modify the properties of the current session.  The request is sent to
@@ -999,7 +1069,9 @@
          *
          * @param requestProfile The requested call video properties.
          */
-        public abstract void onSendSessionModifyRequest(VideoCallProfile requestProfile);
+        public void onSendSessionModifyRequest(VideoCallProfile requestProfile) {
+            // To be implemented by subclass.
+        }
 
         /**te
          * Provides a response to a request to change the current call session video
@@ -1011,21 +1083,27 @@
          *
          * @param responseProfile The response call video properties.
          */
-        public abstract void onSendSessionModifyResponse(VideoCallProfile responseProfile);
+        public void onSendSessionModifyResponse(VideoCallProfile responseProfile) {
+            // To be implemented by subclass.
+        }
 
         /**
          * Issues a request to the video provider to retrieve the camera capabilities.
          * Camera capabilities are reported back to the caller via
          * {@link InCallService.VideoCall.Listener#onCameraCapabilitiesChanged(CallCameraCapabilities)}.
          */
-        public abstract void onRequestCameraCapabilities();
+        public void onRequestCameraCapabilities() {
+            // To be implemented by subclass.
+        }
 
         /**
          * Issues a request to the video telephony framework to retrieve the cumulative data usage for
          * the current call.  Data usage is reported back to the caller via
          * {@link InCallService.VideoCall.Listener#onCallDataUsageChanged}.
          */
-        public abstract void onRequestCallDataUsage();
+        public void onRequestCallDataUsage() {
+            // To be implemented by subclass.
+        }
 
         /**
          * Provides the video telephony framework with the URI of an image to be displayed to remote
@@ -1033,7 +1111,9 @@
          *
          * @param uri URI of image to display.
          */
-        public abstract void onSetPauseImage(String uri);
+        public void onSetPauseImage(String uri) {
+            // To be implemented by subclass.
+        }
 
         /**
          * Invokes callback method defined in {@link InCallService.VideoCall.Listener}.
diff --git a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
index ea61362..6499ec4 100644
--- a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
@@ -350,6 +350,16 @@
         }
     }
 
+    void setConferenceableConnections(String callId, List<String> conferenceableCallIds) {
+        Log.v(this, "setConferenceableConnections: %s, %s", callId, conferenceableCallIds);
+        for (IConnectionServiceAdapter adapter : mAdapters) {
+            try {
+                adapter.setConferenceableConnections(callId, conferenceableCallIds);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
     void startActivityFromInCall(String callId, PendingIntent intent) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
diff --git a/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java
new file mode 100644
index 0000000..1685bd7
--- /dev/null
+++ b/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java
@@ -0,0 +1,399 @@
+/*
+ * 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
+ R* limitations under the License.
+ */
+
+package android.telecomm;
+
+import android.app.PendingIntent;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+
+import com.android.internal.os.SomeArgs;
+import com.android.internal.telecomm.IConnectionServiceAdapter;
+import com.android.internal.telecomm.IVideoCallProvider;
+import com.android.internal.telecomm.RemoteServiceCallback;
+
+import java.util.List;
+
+/**
+ * A component that provides an RPC servant implementation of {@link IConnectionServiceAdapter},
+ * posting incoming messages on the main thread on a client-supplied delegate object.
+ *
+ * TODO: Generate this and similar classes using a compiler starting from AIDL interfaces.
+ *
+ * @hide
+ */
+final class ConnectionServiceAdapterServant {
+    private static final int MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL = 1;
+    private static final int MSG_HANDLE_CREATE_CONNECTION_FAILED = 2;
+    private static final int MSG_HANDLE_CREATE_CONNECTION_CANCELLED = 3;
+    private static final int MSG_SET_ACTIVE = 4;
+    private static final int MSG_SET_RINGING = 5;
+    private static final int MSG_SET_DIALING = 6;
+    private static final int MSG_SET_DISCONNECTED = 7;
+    private static final int MSG_SET_ON_HOLD = 8;
+    private static final int MSG_SET_REQUESTING_RINGBACK = 9;
+    private static final int MSG_SET_CALL_CAPABILITIES = 10;
+    private static final int MSG_SET_IS_CONFERENCED = 11;
+    private static final int MSG_ADD_CONFERENCE_CALL = 12;
+    private static final int MSG_REMOVE_CALL = 13;
+    private static final int MSG_ON_POST_DIAL_WAIT = 14;
+    private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 15;
+    private static final int MSG_SET_VIDEO_STATE = 16;
+    private static final int MSG_SET_VIDEO_CALL_PROVIDER = 17;
+    private static final int MSG_SET_AUDIO_MODE_IS_VOIP = 18;
+    private static final int MSG_SET_STATUS_HINTS = 19;
+    private static final int MSG_SET_HANDLE = 20;
+    private static final int MSG_SET_CALLER_DISPLAY_NAME = 21;
+    private static final int MSG_START_ACTIVITY_FROM_IN_CALL = 22;
+    private static final int MSG_SET_CONFERENCEABLE_CONNECTIONS = 23;
+
+    private final IConnectionServiceAdapter mDelegate;
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            try {
+                internalHandleMessage(msg);
+            } catch (RemoteException e) {
+            }
+        }
+
+        // Internal method defined to centralize handling of RemoteException
+        private void internalHandleMessage(Message msg) throws RemoteException {
+            switch (msg.what) {
+                case MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        mDelegate.handleCreateConnectionSuccessful(
+                                (ConnectionRequest) args.arg1,
+                                (ParcelableConnection) args.arg2);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_HANDLE_CREATE_CONNECTION_FAILED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        mDelegate.handleCreateConnectionFailed(
+                                (ConnectionRequest) args.arg1,
+                                args.argi1,
+                                (String) args.arg2);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_HANDLE_CREATE_CONNECTION_CANCELLED: {
+                    mDelegate.handleCreateConnectionCancelled((ConnectionRequest) msg.obj);
+                    break;
+                }
+                case MSG_SET_ACTIVE:
+                    mDelegate.setActive((String) msg.obj);
+                    break;
+                case MSG_SET_RINGING:
+                    mDelegate.setRinging((String) msg.obj);
+                    break;
+                case MSG_SET_DIALING:
+                    mDelegate.setDialing((String) msg.obj);
+                    break;
+                case MSG_SET_DISCONNECTED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        mDelegate.setDisconnected(
+                                (String) args.arg1, args.argi1, (String) args.arg2);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_SET_ON_HOLD:
+                    mDelegate.setOnHold((String) msg.obj);
+                    break;
+                case MSG_SET_REQUESTING_RINGBACK:
+                    mDelegate.setRequestingRingback((String) msg.obj, msg.arg1 == 1);
+                    break;
+                case MSG_SET_CALL_CAPABILITIES:
+                    mDelegate.setCallCapabilities((String) msg.obj, msg.arg1);
+                    break;
+                case MSG_SET_IS_CONFERENCED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        mDelegate.setIsConferenced((String) args.arg1, (String) args.arg2);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_ADD_CONFERENCE_CALL:
+                    mDelegate.addConferenceCall((String) msg.obj);
+                    break;
+                case MSG_REMOVE_CALL:
+                    mDelegate.removeCall((String) msg.obj);
+                    break;
+                case MSG_ON_POST_DIAL_WAIT: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        mDelegate.onPostDialWait((String) args.arg1, (String) args.arg2);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_QUERY_REMOTE_CALL_SERVICES:
+                    mDelegate.queryRemoteConnectionServices((RemoteServiceCallback) msg.obj);
+                    break;
+                case MSG_SET_VIDEO_STATE:
+                    mDelegate.setVideoState((String) msg.obj, msg.arg1);
+                    break;
+                case MSG_SET_VIDEO_CALL_PROVIDER: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        mDelegate.setVideoCallProvider((String) args.arg1,
+                                (IVideoCallProvider) args.arg2);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_SET_AUDIO_MODE_IS_VOIP:
+                    mDelegate.setAudioModeIsVoip((String) msg.obj, msg.arg1 == 1);
+                    break;
+                case MSG_SET_STATUS_HINTS: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        mDelegate.setStatusHints((String) args.arg1, (StatusHints) args.arg2);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_SET_HANDLE: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        mDelegate.setHandle((String) args.arg1, (Uri) args.arg2, args.argi1);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_SET_CALLER_DISPLAY_NAME: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        mDelegate.setCallerDisplayName(
+                                (String) args.arg1, (String) args.arg2, args.argi1);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_START_ACTIVITY_FROM_IN_CALL: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        mDelegate.startActivityFromInCall(
+                                (String) args.arg1, (PendingIntent) args.arg2);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_SET_CONFERENCEABLE_CONNECTIONS: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        mDelegate.setConferenceableConnections(
+                                (String) args.arg1, (List<String>) args.arg2);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+            }
+        }
+    };
+
+    private final IConnectionServiceAdapter mStub = new IConnectionServiceAdapter.Stub() {
+        @Override
+        public void handleCreateConnectionSuccessful(
+                ConnectionRequest request, ParcelableConnection connection) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = request;
+            args.arg2 = connection;
+            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL, args).sendToTarget();
+        }
+
+        @Override
+        public void handleCreateConnectionFailed(
+                ConnectionRequest request, int errorCode, String errorMessage) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = request;
+            args.argi1 = errorCode;
+            args.arg2 = errorMessage;
+            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_FAILED, args).sendToTarget();
+        }
+
+        @Override
+        public void handleCreateConnectionCancelled(ConnectionRequest request) {
+            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_CANCELLED, request).sendToTarget();
+        }
+
+        @Override
+        public void setActive(String connectionId) {
+            mHandler.obtainMessage(MSG_SET_ACTIVE, connectionId).sendToTarget();
+        }
+
+        @Override
+        public void setRinging(String connectionId) {
+            mHandler.obtainMessage(MSG_SET_RINGING, connectionId).sendToTarget();
+        }
+
+        @Override
+        public void setDialing(String connectionId) {
+            mHandler.obtainMessage(MSG_SET_DIALING, connectionId).sendToTarget();
+        }
+
+        @Override
+        public void setDisconnected(
+                String connectionId, int disconnectCause, String disconnectMessage) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = connectionId;
+            args.arg2 = disconnectMessage;
+            args.argi1 = disconnectCause;
+            mHandler.obtainMessage(MSG_SET_DISCONNECTED, args).sendToTarget();
+        }
+
+        @Override
+        public void setOnHold(String connectionId) {
+            mHandler.obtainMessage(MSG_SET_ON_HOLD, connectionId).sendToTarget();
+        }
+
+        @Override
+        public void setRequestingRingback(String connectionId, boolean ringback) {
+            mHandler.obtainMessage(MSG_SET_REQUESTING_RINGBACK, ringback ? 1 : 0, 0, connectionId)
+                    .sendToTarget();
+        }
+
+        @Override
+        public void setCallCapabilities(String connectionId, int callCapabilities) {
+            mHandler.obtainMessage(MSG_SET_CALL_CAPABILITIES, callCapabilities, 0, connectionId)
+                    .sendToTarget();
+        }
+
+        @Override
+        public void setIsConferenced(String callId, String conferenceCallId) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = conferenceCallId;
+            mHandler.obtainMessage(MSG_SET_IS_CONFERENCED, args).sendToTarget();
+        }
+
+        @Override
+        public void addConferenceCall(String callId) {
+            mHandler.obtainMessage(MSG_ADD_CONFERENCE_CALL, callId).sendToTarget();
+        }
+
+        @Override
+        public void removeCall(String connectionId) {
+            mHandler.obtainMessage(MSG_REMOVE_CALL, connectionId).sendToTarget();
+        }
+
+        @Override
+        public void onPostDialWait(String connectionId, String remainingDigits) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = connectionId;
+            args.arg2 = remainingDigits;
+            mHandler.obtainMessage(MSG_ON_POST_DIAL_WAIT, args).sendToTarget();
+        }
+
+        @Override
+        public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
+            mHandler.obtainMessage(MSG_QUERY_REMOTE_CALL_SERVICES, callback).sendToTarget();
+        }
+
+        @Override
+        public void setVideoState(String connectionId, int videoState) {
+            mHandler.obtainMessage(MSG_SET_VIDEO_STATE, videoState, 0, connectionId).sendToTarget();
+        }
+
+        @Override
+        public void setVideoCallProvider(
+                String connectionId, IVideoCallProvider videoCallProvider) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = connectionId;
+            args.arg2 = videoCallProvider;
+            mHandler.obtainMessage(MSG_SET_VIDEO_CALL_PROVIDER, args).sendToTarget();
+        }
+
+        @Override
+        public final void setAudioModeIsVoip(String connectionId, boolean isVoip) {
+            mHandler.obtainMessage(MSG_SET_AUDIO_MODE_IS_VOIP, isVoip ? 1 : 0, 0,
+                    connectionId).sendToTarget();
+        }
+
+        @Override
+        public final void setStatusHints(String connectionId, StatusHints statusHints) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = connectionId;
+            args.arg2 = statusHints;
+            mHandler.obtainMessage(MSG_SET_STATUS_HINTS, args).sendToTarget();
+        }
+
+        @Override
+        public final void setHandle(String connectionId, Uri handle, int presentation) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = connectionId;
+            args.arg2 = handle;
+            args.argi1 = presentation;
+            mHandler.obtainMessage(MSG_SET_HANDLE, args).sendToTarget();
+        }
+
+        @Override
+        public final void setCallerDisplayName(
+                String connectionId, String callerDisplayName, int presentation) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = connectionId;
+            args.arg2 = callerDisplayName;
+            args.argi1 = presentation;
+            mHandler.obtainMessage(MSG_SET_CALLER_DISPLAY_NAME, args).sendToTarget();
+        }
+
+        @Override
+        public final void startActivityFromInCall(String connectionId, PendingIntent intent) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = connectionId;
+            args.arg2 = intent;
+            mHandler.obtainMessage(MSG_START_ACTIVITY_FROM_IN_CALL, args).sendToTarget();
+        }
+
+        @Override
+        public final void setConferenceableConnections(
+                String connectionId, List<String> conferenceableConnectionIds) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = connectionId;
+            args.arg2 = conferenceableConnectionIds;
+            mHandler.obtainMessage(MSG_SET_CONFERENCEABLE_CONNECTIONS, args).sendToTarget();
+        }
+    };
+
+    public ConnectionServiceAdapterServant(IConnectionServiceAdapter delegate) {
+        mDelegate = delegate;
+    }
+
+    public IConnectionServiceAdapter getStub() {
+        return mStub;
+    }
+}
diff --git a/telecomm/java/android/telecomm/InCallAdapter.java b/telecomm/java/android/telecomm/InCallAdapter.java
index 964686a..279e47d 100644
--- a/telecomm/java/android/telecomm/InCallAdapter.java
+++ b/telecomm/java/android/telecomm/InCallAdapter.java
@@ -219,9 +219,9 @@
      * @param callId The unique ID of the call.
      * @hide
      */
-    public void conference(String callId) {
+    public void conference(String callId, String otherCallId) {
         try {
-            mAdapter.conference(callId);
+            mAdapter.conference(callId, otherCallId);
         } catch (RemoteException ignored) {
         }
     }
diff --git a/telecomm/java/android/telecomm/InCallService.java b/telecomm/java/android/telecomm/InCallService.java
index 14b25dc..83e2957 100644
--- a/telecomm/java/android/telecomm/InCallService.java
+++ b/telecomm/java/android/telecomm/InCallService.java
@@ -41,11 +41,10 @@
     private static final int MSG_SET_IN_CALL_ADAPTER = 1;
     private static final int MSG_ADD_CALL = 2;
     private static final int MSG_UPDATE_CALL = 3;
-    private static final int MSG_SET_POST_DIAL = 4;
-    private static final int MSG_SET_POST_DIAL_WAIT = 5;
-    private static final int MSG_ON_AUDIO_STATE_CHANGED = 6;
-    private static final int MSG_BRING_TO_FOREGROUND = 7;
-    private static final int MSG_START_ACTIVITY = 8;
+    private static final int MSG_SET_POST_DIAL_WAIT = 4;
+    private static final int MSG_ON_AUDIO_STATE_CHANGED = 5;
+    private static final int MSG_BRING_TO_FOREGROUND = 6;
+    private static final int MSG_START_ACTIVITY = 7;
 
     /** Default Handler used to consolidate binder method calls onto a single thread. */
     private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@@ -62,17 +61,6 @@
                 case MSG_UPDATE_CALL:
                     mPhone.internalUpdateCall((ParcelableCall) msg.obj);
                     break;
-                case MSG_SET_POST_DIAL: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        String callId = (String) args.arg1;
-                        String remaining = (String) args.arg2;
-                        mPhone.internalSetPostDial(callId, remaining);
-                    } finally {
-                        args.recycle();
-                    }
-                    break;
-                }
                 case MSG_SET_POST_DIAL_WAIT: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
@@ -124,10 +112,7 @@
 
         @Override
         public void setPostDial(String callId, String remaining) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId;
-            args.arg2 = remaining;
-            mHandler.obtainMessage(MSG_SET_POST_DIAL, args).sendToTarget();
+            // TODO: Unused
         }
 
         @Override
diff --git a/telecomm/java/android/telecomm/ParcelableCall.java b/telecomm/java/android/telecomm/ParcelableCall.java
index e60761a..360e768 100644
--- a/telecomm/java/android/telecomm/ParcelableCall.java
+++ b/telecomm/java/android/telecomm/ParcelableCall.java
@@ -25,6 +25,7 @@
 import com.android.internal.telecomm.IVideoCallProvider;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -51,8 +52,8 @@
     private final List<String> mChildCallIds;
     private final StatusHints mStatusHints;
     private final int mVideoState;
+    private final List<String> mConferenceableCallIds;
 
-    /** @hide */
     public ParcelableCall(
             String id,
             CallState state,
@@ -71,7 +72,8 @@
             String parentCallId,
             List<String> childCallIds,
             StatusHints statusHints,
-            int videoState) {
+            int videoState,
+            List<String> conferenceableCallIds) {
         mId = id;
         mState = state;
         mDisconnectCauseCode = disconnectCauseCode;
@@ -90,6 +92,7 @@
         mChildCallIds = childCallIds;
         mStatusHints = statusHints;
         mVideoState = videoState;
+        mConferenceableCallIds = Collections.unmodifiableList(conferenceableCallIds);
     }
 
     /** The unique ID of the call. */
@@ -183,7 +186,6 @@
 
     /**
      * The conference call to which this call is conferenced. Null if not conferenced.
-     * @hide
      */
     public String getParentCallId() {
         return mParentCallId;
@@ -192,12 +194,15 @@
     /**
      * The child call-IDs if this call is a conference call. Returns an empty list if this is not
      * a conference call or if the conference call contains no children.
-     * @hide
      */
     public List<String> getChildCallIds() {
         return mChildCallIds;
     }
 
+    public List<String> getConferenceableCallIds() {
+        return mConferenceableCallIds;
+    }
+
     /**
      * The status label and icon.
      *
@@ -242,11 +247,13 @@
             source.readList(childCallIds, classLoader);
             StatusHints statusHints = source.readParcelable(classLoader);
             int videoState = source.readInt();
+            List<String> conferenceableCallIds = new ArrayList<>();
+            source.readList(conferenceableCallIds, classLoader);
             return new ParcelableCall(id, state, disconnectCauseCode, disconnectCauseMsg,
                     cannedSmsResponses, capabilities, connectTimeMillis, handle, handlePresentation,
                     callerDisplayName, callerDisplayNamePresentation, gatewayInfo,
                     accountHandle, videoCallProvider, parentCallId, childCallIds, statusHints,
-                    videoState);
+                    videoState, conferenceableCallIds);
         }
 
         @Override
@@ -283,6 +290,7 @@
         destination.writeList(mChildCallIds);
         destination.writeParcelable(mStatusHints, 0);
         destination.writeInt(mVideoState);
+        destination.writeList(mConferenceableCallIds);
     }
 
     @Override
diff --git a/telecomm/java/android/telecomm/ParcelableConnection.java b/telecomm/java/android/telecomm/ParcelableConnection.java
index e0bfab6..2f79004 100644
--- a/telecomm/java/android/telecomm/ParcelableConnection.java
+++ b/telecomm/java/android/telecomm/ParcelableConnection.java
@@ -98,6 +98,18 @@
         return mVideoState;
     }
 
+    @Override
+    public String toString() {
+        return new StringBuilder()
+                .append("ParcelableConnection [act:")
+                .append(mPhoneAccount)
+                .append(", state:")
+                .append(mState)
+                .append(", capabilities:")
+                .append(CallCapabilities.toString(mCapabilities))
+                .toString();
+    }
+
     public static final Parcelable.Creator<ParcelableConnection> CREATOR =
             new Parcelable.Creator<ParcelableConnection> () {
         @Override
diff --git a/telecomm/java/android/telecomm/Phone.java b/telecomm/java/android/telecomm/Phone.java
index b4c8a80..4ad572d 100644
--- a/telecomm/java/android/telecomm/Phone.java
+++ b/telecomm/java/android/telecomm/Phone.java
@@ -100,7 +100,7 @@
         mCallByTelecommCallId.put(parcelableCall.getId(), call);
         mCalls.add(call);
         checkCallTree(parcelableCall);
-        call.internalUpdate(parcelableCall);
+        call.internalUpdate(parcelableCall, mCallByTelecommCallId);
         fireCallAdded(call);
      }
 
@@ -116,19 +116,11 @@
          Call call = mCallByTelecommCallId.get(parcelableCall.getId());
          if (call != null) {
              checkCallTree(parcelableCall);
-             call.internalUpdate(parcelableCall);
+             call.internalUpdate(parcelableCall, mCallByTelecommCallId);
          }
      }
 
     /** {@hide} */
-    final void internalSetPostDial(String telecommId, String remaining) {
-        Call call = mCallByTelecommCallId.get(telecommId);
-        if (call != null) {
-            call.internalSetPostDial(remaining);
-        }
-    }
-
-    /** {@hide} */
     final void internalSetPostDialWait(String telecommId, String remaining) {
         Call call = mCallByTelecommCallId.get(telecommId);
         if (call != null) {
diff --git a/telecomm/java/android/telecomm/RemoteConnection.java b/telecomm/java/android/telecomm/RemoteConnection.java
index ab980e8..197e480 100644
--- a/telecomm/java/android/telecomm/RemoteConnection.java
+++ b/telecomm/java/android/telecomm/RemoteConnection.java
@@ -23,36 +23,168 @@
 
 import com.android.internal.telecomm.IConnectionService;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 /**
  * RemoteConnection object used by RemoteConnectionService.
  */
 public final class RemoteConnection {
+
     public static abstract class Listener {
+        /**
+         * Invoked when the state of this {@code RemoteConnection} has changed. See
+         * {@link #getState()}.
+         *
+         * @param connection The {@code RemoteConnection} invoking this method.
+         * @param state The new state of the {@code RemoteConnection}.
+         */
         public void onStateChanged(RemoteConnection connection, int state) {}
-        public void onDisconnected(RemoteConnection connection, int cause, String message) {}
+
+        /**
+         * Invoked when the parent of this {@code RemoteConnection} has changed. See
+         * {@link #getParent()}.
+         *
+         * @param connection The {@code RemoteConnection} invoking this method.
+         * @param parent The new parent of the {@code RemoteConnection}.
+         */
+        public void onParentChanged(RemoteConnection connection, RemoteConnection parent) {}
+
+        /**
+         * Invoked when the children of this {@code RemoteConnection} have changed. See
+         * {@link #getChildren()}.
+         *
+         * @param connection The {@code RemoteConnection} invoking this method.
+         * @param children The new children of the {@code RemoteConnection}.
+         */
+        public void onChildrenChanged(
+                RemoteConnection connection, List<RemoteConnection> children) {}
+
+        /**
+         * Invoked when this {@code RemoteConnection} is disconnected.
+         *
+         * @param connection The {@code RemoteConnection} invoking this method.
+         * @param disconnectCauseCode The failure code ({@see DisconnectCause}) associated with this
+         *         failed connection.
+         * @param disconnectCauseMessage The reason for the connection failure. This will not be
+         *         displayed to the user.
+         */
+        public void onDisconnected(
+                RemoteConnection connection,
+                int disconnectCauseCode,
+                String disconnectCauseMessage) {}
+
+        /**
+         * Invoked when this {@code RemoteConnection} is requesting ringback. See
+         * {@link #isRequestingRingback()}.
+         *
+         * @param connection The {@code RemoteConnection} invoking this method.
+         * @param ringback Whether the {@code RemoteConnection} is requesting ringback.
+         */
         public void onRequestingRingback(RemoteConnection connection, boolean ringback) {}
+
+        /**
+         * Indicates that the call capabilities of this {@code RemoteConnection} have changed.
+         * See {@link #getCallCapabilities()}.
+         *
+         * @param connection The {@code RemoteConnection} invoking this method.
+         * @param callCapabilities The new call capabilities of the {@code RemoteConnection}.
+         */
         public void onCallCapabilitiesChanged(RemoteConnection connection, int callCapabilities) {}
-        public void onPostDialWait(RemoteConnection connection, String remainingDigits) {}
+
+        /**
+         * Invoked when the post-dial sequence in the outgoing {@code Connection} has reached a
+         * pause character. This causes the post-dial signals to stop pending user confirmation. An
+         * implementation should present this choice to the user and invoke
+         * {@link #postDialContinue(boolean)} when the user makes the choice.
+         *
+         * @param connection The {@code RemoteConnection} invoking this method.
+         * @param remainingPostDialSequence The post-dial characters that remain to be sent.
+         */
+        public void onPostDialWait(RemoteConnection connection, String remainingPostDialSequence) {}
+
+        /**
+         * Indicates that the VOIP audio status of this {@code RemoteConnection} has changed.
+         * See {@link #getAudioModeIsVoip()}.
+         *
+         * @param connection The {@code RemoteConnection} invoking this method.
+         * @param isVoip Whether the new audio state of the {@code RemoteConnection} is VOIP.
+         */
         public void onAudioModeIsVoipChanged(RemoteConnection connection, boolean isVoip) {}
+
+        /**
+         * Indicates that the status hints of this {@code RemoteConnection} have changed. See
+         * {@link #getStatusHints()} ()}.
+         *
+         * @param connection The {@code RemoteConnection} invoking this method.
+         * @param statusHints The new status hints of the {@code RemoteConnection}.
+         */
         public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {}
+
+        /**
+         * Indicates that the handle (e.g., phone number) of this {@code RemoteConnection} has
+         * changed. See {@link #getHandle()} and {@link #getHandlePresentation()}.
+         *
+         * @param connection The {@code RemoteConnection} invoking this method.
+         * @param handle The new handle of the {@code RemoteConnection}.
+         * @param presentation The {@link CallPropertyPresentation} which controls how the
+         *         handle is shown.
+         */
         public void onHandleChanged(RemoteConnection connection, Uri handle, int presentation) {}
+
+        /**
+         * Indicates that the caller display name of this {@code RemoteConnection} has changed.
+         * See {@link #getCallerDisplayName()} and {@link #getCallerDisplayNamePresentation()}.
+         *
+         * @param connection The {@code RemoteConnection} invoking this method.
+         * @param callerDisplayName The new caller display name of the {@code RemoteConnection}.
+         * @param presentation The {@link CallPropertyPresentation} which controls how the
+         *         caller display name is shown.
+         */
         public void onCallerDisplayNameChanged(
                 RemoteConnection connection, String callerDisplayName, int presentation) {}
+
+        /**
+         * Indicates that the video state of this {@code RemoteConnection} has changed.
+         * See {@link #getVideoState()}.
+         *
+         * @param connection The {@code RemoteConnection} invoking this method.
+         * @param videoState The new video state of the {@code RemoteConnection}.
+         */
         public void onVideoStateChanged(RemoteConnection connection, int videoState) {}
+
+        /**
+         * Indicates that this {@code RemoteConnection} is requesting that the in-call UI
+         * launch the specified activity.
+         *
+         * @param connection The {@code RemoteConnection} invoking this method.
+         * @param intent A {@link PendingIntent} that the {@code RemoteConnection} wishes to
+         *         have launched on its behalf.
+         */
         public void onStartActivityFromInCall(RemoteConnection connection, PendingIntent intent) {}
+
+        /**
+         * Indicates that this {@code RemoteConnection} has been destroyed. No further requests
+         * should be made to the {@code RemoteConnection}, and references to it should be cleared.
+         *
+         * @param connection The {@code RemoteConnection} invoking this method.
+         */
         public void onDestroyed(RemoteConnection connection) {}
+        public void onConferenceableConnectionsChanged(
+                RemoteConnection connection, List<RemoteConnection> conferenceableConnections) {}
     }
 
     private IConnectionService mConnectionService;
     private final String mConnectionId;
     private final Set<Listener> mListeners = new HashSet<>();
+    private final Set<RemoteConnection> mConferenceableConnections = new HashSet<>();
 
     private int mState = Connection.State.NEW;
-    private int mDisconnectCause = DisconnectCause.NOT_VALID;
-    private String mDisconnectMessage;
+    private int mDisconnectCauseCode = DisconnectCause.NOT_VALID;
+    private String mDisconnectCauseMessage;
     private boolean mRequestingRingback;
     private boolean mConnected;
     private int mCallCapabilities;
@@ -69,10 +201,9 @@
     /**
      * @hide
      */
-    RemoteConnection(IConnectionService connectionService, ConnectionRequest request,
-            boolean isIncoming) {
+    RemoteConnection(IConnectionService connectionService, ConnectionRequest request) {
         mConnectionService = connectionService;
-        mConnectionId = request.getCallId();
+        mConnectionId = request == null ? "NULL" : request.getCallId();
 
         mConnected = true;
         mState = Connection.State.INITIALIZING;
@@ -87,73 +218,161 @@
      * @param failureMessage
      */
     private RemoteConnection(int failureCode, String failureMessage) {
-        this(null, null, true);
+        this(null, null);
         mConnected = false;
         mState = Connection.State.FAILED;
         mFailureCode = failureCode;
         mFailureMessage = failureMessage;
     }
 
+    /**
+     * Adds a listener to this {@code RemoteConnection}.
+     *
+     * @param listener A {@code Listener}.
+     */
     public void addListener(Listener listener) {
         mListeners.add(listener);
     }
 
+    /**
+     * Removes a listener from this {@code RemoteConnection}.
+     *
+     * @param listener A {@code Listener}.
+     */
     public void removeListener(Listener listener) {
         mListeners.remove(listener);
     }
 
+    /**
+     * Obtains the parent of this {@code RemoteConnection} in a conference, if any.
+     *
+     * @return The parent {@code RemoteConnection}, or {@code null} if this {@code RemoteConnection}
+     * is not a child of any conference {@code RemoteConnection}s.
+     */
+    public RemoteConnection getParent() { return null; }
+
+    /**
+     * Obtains the children of this conference {@code RemoteConnection}, if any.
+     *
+     * @return The children of this {@code RemoteConnection} if this {@code RemoteConnection} is
+     * a conference, or an empty {@code List} otherwise.
+     */
+    public List<RemoteConnection> getChildren() { return null; }
+
+    /**
+     * Obtains the state of this {@code RemoteConnection}.
+     *
+     * @return A state value, chosen from the {@code STATE_*} constants.
+     */
     public int getState() {
         return mState;
     }
 
-    public int getDisconnectCause() {
-        return mDisconnectCause;
+    /**
+     * @return For a {@link Connection.State#DISCONNECTED} {@code RemoteConnection}, the
+     * disconnect cause expressed as a code chosen from among those declared in
+     * {@link DisconnectCause}.
+     */
+    public int getDisconnectCauseCode() {
+        return mDisconnectCauseCode;
     }
 
-    public String getDisconnectMessage() {
-        return mDisconnectMessage;
+    /**
+     * @return For a {@link Connection.State#DISCONNECTED} {@code RemoteConnection}, an optional
+     * reason for disconnection expressed as a free text message.
+     */
+    public String getDisconnectCauseMessage() {
+        return mDisconnectCauseMessage;
     }
 
+    /**
+     * @return A bitmask of the capabilities of the {@code RemoteConnection}, as defined in
+     *         {@link CallCapabilities}.
+     */
     public int getCallCapabilities() {
         return mCallCapabilities;
     }
 
+    /**
+     * @return {@code true} if the {@code RemoteConnection}'s current audio mode is VOIP.
+     */
     public boolean getAudioModeIsVoip() {
         return mAudioModeIsVoip;
     }
 
+    /**
+     * @return The current {@link android.telecomm.StatusHints} of this {@code RemoteConnection},
+     * or {@code null} if none have been set.
+     */
     public StatusHints getStatusHints() {
         return mStatusHints;
     }
 
+    /**
+     * @return The handle (e.g., phone number) to which the {@code RemoteConnection} is currently
+     * connected.
+     */
     public Uri getHandle() {
         return mHandle;
     }
 
+    /**
+     * @return The presentation requirements for the handle. See
+     * {@link android.telecomm.CallPropertyPresentation} for valid values.
+     */
     public int getHandlePresentation() {
         return mHandlePresentation;
     }
 
+    /**
+     * @return The display name for the caller.
+     */
     public String getCallerDisplayName() {
         return mCallerDisplayName;
     }
 
+    /**
+     * @return The presentation requirements for the caller display name. See
+     * {@link android.telecomm.CallPropertyPresentation} for valid values.
+     */
     public int getCallerDisplayNamePresentation() {
         return mCallerDisplayNamePresentation;
     }
 
+    /**
+     * @return The video state of the {@code RemoteConnection}. See
+     * {@link VideoCallProfile.VideoState}.
+     */
     public int getVideoState() {
         return mVideoState;
     }
 
+    /**
+     * @return The failure code ({@see DisconnectCause}) associated with this failed
+     * {@code RemoteConnection}.
+     */
     public int getFailureCode() {
         return mFailureCode;
     }
 
+    /**
+     * @return The reason for the connection failure. This will not be displayed to the user.
+     */
     public String getFailureMessage() {
         return mFailureMessage;
     }
 
+    /**
+     * @return Whether the {@code RemoteConnection} is requesting that the framework play a
+     * ringback tone on its behalf.
+     */
+    public boolean isRequestingRingback() {
+        return false;
+    }
+
+    /**
+     * Instructs this {@code RemoteConnection} to abort.
+     */
     public void abort() {
         try {
             if (mConnected) {
@@ -163,6 +382,10 @@
         }
     }
 
+    /**
+     * Instructs this {@link Connection.State#RINGING} {@code RemoteConnection} to answer.
+     * @param videoState The video state in which to answer the call.
+     */
     public void answer(int videoState) {
         try {
             if (mConnected) {
@@ -172,6 +395,9 @@
         }
     }
 
+    /**
+     * Instructs this {@link Connection.State#RINGING} {@code RemoteConnection} to reject.
+     */
     public void reject() {
         try {
             if (mConnected) {
@@ -181,6 +407,9 @@
         }
     }
 
+    /**
+     * Instructs this {@code RemoteConnection} to go on hold.
+     */
     public void hold() {
         try {
             if (mConnected) {
@@ -190,6 +419,9 @@
         }
     }
 
+    /**
+     * Instructs this {@link Connection.State#HOLDING} call to release from hold.
+     */
     public void unhold() {
         try {
             if (mConnected) {
@@ -199,6 +431,9 @@
         }
     }
 
+    /**
+     * Instructs this {@code RemoteConnection} to disconnect.
+     */
     public void disconnect() {
         try {
             if (mConnected) {
@@ -208,7 +443,16 @@
         }
     }
 
-    public void playDtmf(char digit) {
+    /**
+     * Instructs this {@code RemoteConnection} to play a dual-tone multi-frequency signaling
+     * (DTMF) tone.
+     *
+     * Any other currently playing DTMF tone in the specified call is immediately stopped.
+     *
+     * @param digit A character representing the DTMF digit for which to play the tone. This
+     *         value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
+     */
+    public void playDtmfTone(char digit) {
         try {
             if (mConnected) {
                 mConnectionService.playDtmfTone(mConnectionId, digit);
@@ -217,7 +461,14 @@
         }
     }
 
-    public void stopDtmf() {
+    /**
+     * Instructs this {@code RemoteConnection} to stop any dual-tone multi-frequency signaling
+     * (DTMF) tone currently playing.
+     *
+     * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is
+     * currently playing, this method will do nothing.
+     */
+    public void stopDtmfTone() {
         try {
             if (mConnected) {
                 mConnectionService.stopDtmfTone(mConnectionId);
@@ -226,6 +477,27 @@
         }
     }
 
+    /**
+     * Instructs this {@code RemoteConnection} to continue playing a post-dial DTMF string.
+     *
+     * A post-dial DTMF string is a string of digits following the first instance of either
+     * {@link TelecommManager#DTMF_CHARACTER_WAIT} or {@link TelecommManager#DTMF_CHARACTER_PAUSE}.
+     * These digits are immediately sent as DTMF tones to the recipient as soon as the
+     * connection is made.
+     *
+     * If the DTMF string contains a {@link TelecommManager#DTMF_CHARACTER_PAUSE} symbol, this
+     * {@code RemoteConnection} will temporarily pause playing the tones for a pre-defined period
+     * of time.
+     *
+     * If the DTMF string contains a {@link TelecommManager#DTMF_CHARACTER_WAIT} symbol, this
+     * {@code RemoteConnection} will pause playing the tones and notify listeners via
+     * {@link Listener#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app
+     * should display to the user an indication of this state and an affordance to continue
+     * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
+     * app should invoke the {@link #postDialContinue(boolean)} method.
+     *
+     * @param proceed Whether or not to continue with the post-dial sequence.
+     */
     public void postDialContinue(boolean proceed) {
         try {
             if (mConnected) {
@@ -235,6 +507,10 @@
         }
     }
 
+    /**
+     * Instructs this {@code RemoteConnection} to swap itself with an existing background call,
+     * if one such call exists.
+     */
     public void swapWithBackgroundCall() {
         try {
             if (mConnected) {
@@ -244,6 +520,11 @@
         }
     }
 
+    /**
+     * Set the audio state of this {@code RemoteConnection}.
+     *
+     * @param state The audio state of this {@code RemoteConnection}.
+     */
     public void setAudioState(CallAudioState state) {
         try {
             if (mConnected) {
@@ -271,8 +552,8 @@
     void setDisconnected(int cause, String message) {
         if (mState != Connection.State.DISCONNECTED) {
             mState = Connection.State.DISCONNECTED;
-            mDisconnectCause = cause;
-            mDisconnectMessage = message;
+            mDisconnectCauseCode = cause;
+            mDisconnectCauseMessage = message;
 
             for (Listener l : mListeners) {
                 l.onDisconnected(this, cause, message);
@@ -383,10 +664,13 @@
     }
 
     /** @hide */
-    void setConnectionService(IConnectionService connectionService) {
-        mConnectionService = connectionService;
-        mConnectionService = null;
-        setState(Connection.State.NEW);
+    void setConferenceableConnections(List<RemoteConnection> conferenceableConnections) {
+        mConferenceableConnections.clear();
+        mConferenceableConnections.addAll(conferenceableConnections);
+        for (Listener l : mListeners) {
+            l.onConferenceableConnectionsChanged(
+                    this, new ArrayList<RemoteConnection>(mConferenceableConnections));
+        }
     }
 
     /**
@@ -396,7 +680,6 @@
      * @return a failed {@link RemoteConnection}
      *
      * @hide
-     *
      */
     public static RemoteConnection failure(int failureCode, String failureMessage) {
         return new RemoteConnection(failureCode, failureMessage);
diff --git a/telecomm/java/android/telecomm/RemoteConnectionManager.java b/telecomm/java/android/telecomm/RemoteConnectionManager.java
index ce8bfbd..365ed5b 100644
--- a/telecomm/java/android/telecomm/RemoteConnectionManager.java
+++ b/telecomm/java/android/telecomm/RemoteConnectionManager.java
@@ -17,14 +17,11 @@
 package android.telecomm;
 
 import android.content.ComponentName;
-import android.net.Uri;
 import android.os.RemoteException;
 
 import com.android.internal.telecomm.IConnectionService;
 
 import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
 import java.util.Map;
 
 /**
@@ -37,18 +34,13 @@
         if (!mRemoteConnectionServices.containsKey(componentName)) {
             try {
                 RemoteConnectionService remoteConnectionService =
-                        new RemoteConnectionService(componentName, connectionService);
+                        new RemoteConnectionService(connectionService);
                 mRemoteConnectionServices.put(componentName, remoteConnectionService);
             } catch (RemoteException ignored) {
             }
         }
     }
 
-    List<PhoneAccountHandle> getAccounts(Uri handle) {
-        List<PhoneAccountHandle> accountHandles = new LinkedList<>();
-        return accountHandles;
-    }
-
     public RemoteConnection createRemoteConnection(
             PhoneAccountHandle connectionManagerPhoneAccount,
             ConnectionRequest request,
diff --git a/telecomm/java/android/telecomm/RemoteConnectionService.java b/telecomm/java/android/telecomm/RemoteConnectionService.java
index 501e843..9325bbb 100644
--- a/telecomm/java/android/telecomm/RemoteConnectionService.java
+++ b/telecomm/java/android/telecomm/RemoteConnectionService.java
@@ -17,21 +17,23 @@
 package android.telecomm;
 
 import android.app.PendingIntent;
-import android.content.ComponentName;
 import android.net.Uri;
-import android.os.Handler;
+import android.os.IBinder;
 import android.os.IBinder.DeathRecipient;
-import android.os.Message;
 import android.os.RemoteException;
 import android.telephony.DisconnectCause;
-import android.text.TextUtils;
 
-import com.android.internal.os.SomeArgs;
 import com.android.internal.telecomm.IConnectionService;
 import com.android.internal.telecomm.IConnectionServiceAdapter;
 import com.android.internal.telecomm.IVideoCallProvider;
 import com.android.internal.telecomm.RemoteServiceCallback;
 
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.Collections;
+import java.util.List;
 import java.util.UUID;
 
 /**
@@ -39,369 +41,199 @@
  *
  * @hide
  */
-final class RemoteConnectionService implements DeathRecipient {
-    private static final int MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL = 1;
-    private static final int MSG_HANDLE_CREATE_CONNECTION_FAILED = 2;
-    private static final int MSG_HANDLE_CREATE_CONNECTION_CANCELLED = 3;
-    private static final int MSG_SET_ACTIVE = 4;
-    private static final int MSG_SET_RINGING = 5;
-    private static final int MSG_SET_DIALING = 6;
-    private static final int MSG_SET_DISCONNECTED = 7;
-    private static final int MSG_SET_ON_HOLD = 8;
-    private static final int MSG_SET_REQUESTING_RINGBACK = 9;
-    private static final int MSG_SET_CALL_CAPABILITIES = 10;
-    private static final int MSG_SET_IS_CONFERENCED = 11;
-    private static final int MSG_ADD_CONFERENCE_CALL = 12;
-    private static final int MSG_REMOVE_CALL = 13;
-    private static final int MSG_ON_POST_DIAL_WAIT = 14;
-    private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 15;
-    private static final int MSG_SET_VIDEO_STATE = 16;
-    private static final int MSG_SET_CALL_VIDEO_PROVIDER = 17;
-    private static final int MSG_SET_AUDIO_MODE_IS_VOIP = 18;
-    private static final int MSG_SET_STATUS_HINTS = 19;
-    private static final int MSG_SET_HANDLE = 20;
-    private static final int MSG_SET_CALLER_DISPLAY_NAME = 21;
-    private static final int MSG_START_ACTIVITY_FROM_IN_CALL = 22;
+final class RemoteConnectionService {
 
-    private final IConnectionService mConnectionService;
-    private final ComponentName mComponentName;
+    private static final RemoteConnection NULL_CONNECTION = new RemoteConnection(null, null);
 
-    private String mConnectionId;
-    // Remote connection services only support a single connection.
-    private RemoteConnection mConnection;
-
-    private final Handler mHandler = new Handler() {
+    private final IConnectionServiceAdapter mServantDelegate = new IConnectionServiceAdapter() {
         @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        ConnectionRequest request = (ConnectionRequest) args.arg1;
-                        if (isPendingConnection(request.getCallId())) {
-                            ParcelableConnection parcel = (ParcelableConnection) args.arg2;
-                            mConnection.setState(parcel.getState());
-                            mConnection.setCallCapabilities(parcel.getCapabilities());
-                            mConnection.setHandle(
-                                    parcel.getHandle(), parcel.getHandlePresentation());
-                            mConnection.setCallerDisplayName(
-                                    parcel.getCallerDisplayName(),
-                                    parcel.getCallerDisplayNamePresentation());
-                            // TODO: Do we need to support video providers for remote connections?
-                        }
-                    } finally {
-                        args.recycle();
-                    }
-                    break;
-                }
-                case MSG_HANDLE_CREATE_CONNECTION_FAILED: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        ConnectionRequest request = (ConnectionRequest) args.arg1;
-                        if (isPendingConnection(request.getCallId())) {
-                            // TODO: How do we propogate the failure codes?
-                            destroyConnection();
-                        }
-                    } finally {
-                        args.recycle();
-                    }
-                    break;
-                }
-                case MSG_HANDLE_CREATE_CONNECTION_CANCELLED: {
-                    ConnectionRequest request = (ConnectionRequest) msg.obj;
-                    if (isPendingConnection(request.getCallId())) {
-                        destroyConnection();
-                    }
-                    break;
-                }
-                case MSG_SET_ACTIVE:
-                    if (isCurrentConnection(msg.obj)) {
-                        mConnection.setState(Connection.State.ACTIVE);
-                    }
-                    break;
-                case MSG_SET_RINGING:
-                    if (isCurrentConnection(msg.obj)) {
-                        mConnection.setState(Connection.State.RINGING);
-                    }
-                    break;
-                case MSG_SET_DIALING:
-                    if (isCurrentConnection(msg.obj)) {
-                        mConnection.setState(Connection.State.DIALING);
-                    }
-                    break;
-                case MSG_SET_DISCONNECTED: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        if (isCurrentConnection(args.arg1)) {
-                            mConnection.setDisconnected(args.argi1, (String) args.arg2);
-                        }
-                    } finally {
-                        args.recycle();
-                    }
-                    break;
-                }
-                case MSG_SET_ON_HOLD:
-                    if (isCurrentConnection(msg.obj)) {
-                        mConnection.setState(Connection.State.HOLDING);
-                    }
-                    break;
-                case MSG_SET_REQUESTING_RINGBACK:
-                    if (isCurrentConnection(msg.obj)) {
-                        mConnection.setRequestingRingback(msg.arg1 == 1);
-                    }
-                    break;
-                case MSG_SET_CALL_CAPABILITIES:
-                    if (isCurrentConnection(msg.obj)) {
-                        mConnection.setCallCapabilities(msg.arg1);
-                    }
-                    break;
-                case MSG_SET_IS_CONFERENCED:
-                    // not supported for remote connections.
-                    break;
-                case MSG_ADD_CONFERENCE_CALL:
-                    // not supported for remote connections.
-                    break;
-                case MSG_REMOVE_CALL:
-                    if (isCurrentConnection(msg.obj)) {
-                        destroyConnection();
-                    }
-                    break;
-                case MSG_ON_POST_DIAL_WAIT: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        if (isCurrentConnection(args.arg1)) {
-                            mConnection.setPostDialWait((String) args.arg2);
-                        }
-                    } finally {
-                        args.recycle();
-                    }
-                    break;
-                }
-                case MSG_QUERY_REMOTE_CALL_SERVICES:
-                    // Not supported from remote connection service.
-                    break;
-                case MSG_SET_VIDEO_STATE:
-                    if (isCurrentConnection(msg.obj)) {
-                        mConnection.setVideoState(msg.arg1);
-                    }
-                    break;
-                case MSG_SET_CALL_VIDEO_PROVIDER:
-                    // not supported for remote connections.
-                    break;
-                case MSG_SET_AUDIO_MODE_IS_VOIP:
-                    if (isCurrentConnection(msg.obj)) {
-                        mConnection.setAudioModeIsVoip(msg.arg1 == 1);
-                    }
-                    break;
-                case MSG_SET_STATUS_HINTS: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        if (isCurrentConnection(args.arg1)) {
-                            mConnection.setStatusHints((StatusHints) args.arg2);
-                        }
-                    } finally {
-                        args.recycle();
-                    }
-                    break;
-                }
-                case MSG_SET_HANDLE: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        if (isCurrentConnection(args.arg1)) {
-                            mConnection.setHandle((Uri) args.arg2, args.argi1);
-                        }
-                    } finally {
-                        args.recycle();
-                    }
-                    break;
-                }
-                case MSG_SET_CALLER_DISPLAY_NAME: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        if (isCurrentConnection(msg.arg1)) {
-                            mConnection.setCallerDisplayName((String) args.arg2, args.argi1);
-                        }
-                    } finally {
-                        args.recycle();
-                    }
-                    break;
-                }
-                case MSG_START_ACTIVITY_FROM_IN_CALL: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        if (isCurrentConnection(msg.arg1)) {
-                            mConnection.startActivityFromInCall((PendingIntent) args.arg2);
-                        }
-                    } finally {
-                        args.recycle();
-                    }
-                    break;
-                }
+        public void handleCreateConnectionSuccessful(ConnectionRequest request,
+                ParcelableConnection parcel) {
+            RemoteConnection connection = findConnectionForAction(
+                    request.getCallId(), "handleCreateConnectionSuccessful");
+            if (connection != NULL_CONNECTION && mPendingConnections.contains(connection)) {
+                mPendingConnections.remove(connection);
+                connection.setState(parcel.getState());
+                connection.setCallCapabilities(parcel.getCapabilities());
+                connection.setHandle(
+                        parcel.getHandle(), parcel.getHandlePresentation());
+                connection.setCallerDisplayName(
+                        parcel.getCallerDisplayName(),
+                        parcel.getCallerDisplayNamePresentation());
+                // TODO: Do we need to support video providers for remote connections?
             }
         }
 
-
-    };
-
-    private final IConnectionServiceAdapter mAdapter = new IConnectionServiceAdapter.Stub() {
         @Override
-        public void handleCreateConnectionSuccessful(
-                ConnectionRequest request, ParcelableConnection connection) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = request;
-            args.arg2 = connection;
-            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL, args).sendToTarget();
-        }
-
-        @Override
-        public void handleCreateConnectionFailed(
-                ConnectionRequest request, int errorCode, String errorMessage) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = request;
-            args.argi1 = errorCode;
-            args.arg2 = errorMessage;
-            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_FAILED, args).sendToTarget();
+        public void handleCreateConnectionFailed(ConnectionRequest request, int errorCode,
+                String errorMessage) {
+            // TODO: How do we propagate the failure codes?
+            findConnectionForAction(
+                    request.getCallId(), "handleCreateConnectionFailed")
+                    .setDestroyed();
         }
 
         @Override
         public void handleCreateConnectionCancelled(ConnectionRequest request) {
-            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_CANCELLED, request).sendToTarget();
+            findConnectionForAction(
+                    request.getCallId(), "handleCreateConnectionCancelled")
+                    .setDestroyed();
         }
 
         @Override
-        public void setActive(String connectionId) {
-            mHandler.obtainMessage(MSG_SET_ACTIVE, connectionId).sendToTarget();
+        public void setActive(String callId) {
+            findConnectionForAction(callId, "setActive")
+                    .setState(Connection.State.ACTIVE);
         }
 
         @Override
-        public void setRinging(String connectionId) {
-            mHandler.obtainMessage(MSG_SET_RINGING, connectionId).sendToTarget();
+        public void setRinging(String callId) {
+            findConnectionForAction(callId, "setRinging")
+                    .setState(Connection.State.RINGING);
         }
 
         @Override
-        public void setDialing(String connectionId) {
-            mHandler.obtainMessage(MSG_SET_DIALING, connectionId).sendToTarget();
+        public void setDialing(String callId) {
+            findConnectionForAction(callId, "setDialing")
+                    .setState(Connection.State.DIALING);
         }
 
         @Override
-        public void setDisconnected(
-                String connectionId, int disconnectCause, String disconnectMessage) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = connectionId;
-            args.arg2 = disconnectMessage;
-            args.argi1 = disconnectCause;
-            mHandler.obtainMessage(MSG_SET_DISCONNECTED, args).sendToTarget();
+        public void setDisconnected(String callId, int disconnectCause,
+                String disconnectMessage) {
+            findConnectionForAction(callId, "setDisconnected")
+                    .setDisconnected(disconnectCause, disconnectMessage);
         }
 
         @Override
-        public void setOnHold(String connectionId) {
-            mHandler.obtainMessage(MSG_SET_ON_HOLD, connectionId).sendToTarget();
+        public void setOnHold(String callId) {
+            findConnectionForAction(callId, "setOnHold")
+                    .setState(Connection.State.HOLDING);
         }
 
         @Override
-        public void setRequestingRingback(String connectionId, boolean ringback) {
-            mHandler.obtainMessage(MSG_SET_REQUESTING_RINGBACK, ringback ? 1 : 0, 0, connectionId)
-                    .sendToTarget();
+        public void setRequestingRingback(String callId, boolean ringing) {
+            findConnectionForAction(callId, "setRequestingRingback")
+                    .setRequestingRingback(ringing);
         }
 
         @Override
-        public void setCallCapabilities(String connectionId, int callCapabilities) {
-            mHandler.obtainMessage(MSG_SET_CALL_CAPABILITIES, callCapabilities, 0, connectionId)
-                    .sendToTarget();
+        public void setCallCapabilities(String callId, int callCapabilities) {
+            findConnectionForAction("callId", "setCallCapabilities")
+                    .setCallCapabilities(callCapabilities);
         }
 
         @Override
-        public void setIsConferenced(String connectionId, String conferenceConnectionId) {
+        public void setIsConferenced(String callId, String conferenceCallId) {
             // not supported for remote connections.
         }
 
         @Override
-        public void addConferenceCall(String connectionId) {
+        public void addConferenceCall(String callId) {
             // not supported for remote connections.
         }
 
         @Override
-        public void removeCall(String connectionId) {
-            mHandler.obtainMessage(MSG_REMOVE_CALL, connectionId).sendToTarget();
+        public void removeCall(String callId) {
+            findConnectionForAction(callId, "removeCall")
+                    .setDestroyed();
         }
 
         @Override
-        public void onPostDialWait(String connectionId, String remainingDigits) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = connectionId;
-            args.arg2 = remainingDigits;
-            mHandler.obtainMessage(MSG_ON_POST_DIAL_WAIT, args).sendToTarget();
+        public void onPostDialWait(String callId, String remaining) {
+            findConnectionForAction(callId, "onPostDialWait")
+                    .setPostDialWait(remaining);
         }
 
         @Override
         public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
-            try {
-                // Not supported from remote connection service.
-                callback.onError();
-            } catch (RemoteException e) {
-            }
+            // Not supported from remote connection service.
         }
 
         @Override
-        public void setVideoState(String connectionId, int videoState) {
-            mHandler.obtainMessage(MSG_SET_VIDEO_STATE, videoState, 0, connectionId).sendToTarget();
-        }
-
-        @Override
-        public void setVideoCallProvider(
-                String connectionId, IVideoCallProvider videoCallProvider) {
+        public void setVideoCallProvider(String callId,
+                IVideoCallProvider videoCallProvider) {
             // not supported for remote connections.
         }
 
         @Override
-        public final void setAudioModeIsVoip(String connectionId, boolean isVoip) {
-            mHandler.obtainMessage(MSG_SET_AUDIO_MODE_IS_VOIP, isVoip ? 1 : 0, 0,
-                    connectionId).sendToTarget();
+        public void setVideoState(String callId, int videoState) {
+            findConnectionForAction(callId, "setVideoState")
+                    .setVideoState(videoState);
         }
 
         @Override
-        public final void setStatusHints(String connectionId, StatusHints statusHints) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = connectionId;
-            args.arg2 = statusHints;
-            mHandler.obtainMessage(MSG_SET_STATUS_HINTS, args).sendToTarget();
+        public void setAudioModeIsVoip(String callId, boolean isVoip) {
+            findConnectionForAction(callId, "setAudioModeIsVoip")
+                    .setAudioModeIsVoip(isVoip);
         }
 
         @Override
-        public final void setHandle(String connectionId, Uri handle, int presentation) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = connectionId;
-            args.arg2 = handle;
-            args.argi1 = presentation;
-            mHandler.obtainMessage(MSG_SET_HANDLE, args).sendToTarget();
+        public void setStatusHints(String callId, StatusHints statusHints) {
+            findConnectionForAction(callId, "setStatusHints")
+                    .setStatusHints(statusHints);
         }
 
         @Override
-        public final void setCallerDisplayName(
-                String connectionId, String callerDisplayName, int presentation) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = connectionId;
-            args.arg2 = callerDisplayName;
-            args.argi1 = presentation;
-            mHandler.obtainMessage(MSG_SET_CALLER_DISPLAY_NAME, args).sendToTarget();
+        public void setHandle(String callId, Uri handle, int presentation) {
+            findConnectionForAction(callId, "setHandle")
+                    .setHandle(handle, presentation);
         }
 
         @Override
-        public final void startActivityFromInCall(String connectionId, PendingIntent intent) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = connectionId;
-            args.arg2 = intent;
-            mHandler.obtainMessage(MSG_START_ACTIVITY_FROM_IN_CALL, args).sendToTarget();
+        public void setCallerDisplayName(String callId, String callerDisplayName,
+                int presentation) {
+            findConnectionForAction(callId, "setCallerDisplayName")
+                    .setCallerDisplayName(callerDisplayName, presentation);
+        }
+
+        @Override
+        public void startActivityFromInCall(String callId, PendingIntent intent) {
+            findConnectionForAction(callId, "startActivityFromInCall")
+                    .startActivityFromInCall(intent);
+        }
+
+        @Override
+        public IBinder asBinder() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public final void setConferenceableConnections(
+                String callId, List<String> conferenceableConnectionIds) {
+
+            // TODO: When we support more than 1 remote connection, this should
+            // loop through the incoming list of connection IDs and acquire the list
+            // of remote connections which correspond to the IDs. That list should
+            // be set onto the remote connections.
+            findConnectionForAction(callId, "setConferenceableConnections")
+                    .setConferenceableConnections(Collections.<RemoteConnection>emptyList());
         }
     };
 
-    RemoteConnectionService(ComponentName componentName, IConnectionService connectionService)
-            throws RemoteException {
-        mComponentName = componentName;
-        mConnectionService = connectionService;
+    private final ConnectionServiceAdapterServant mServant =
+            new ConnectionServiceAdapterServant(mServantDelegate);
 
-        mConnectionService.addConnectionServiceAdapter(mAdapter);
-        mConnectionService.asBinder().linkToDeath(this, 0);
+    private final DeathRecipient mDeathRecipient = new DeathRecipient() {
+        @Override
+        public void binderDied() {
+            for (RemoteConnection c : mConnectionById.values()) {
+                c.setDestroyed();
+            }
+            mConnectionById.clear();
+            mPendingConnections.clear();
+            mConnectionService.asBinder().unlinkToDeath(mDeathRecipient, 0);
+        }
+    };
+
+    private final IConnectionService mConnectionService;
+    private final Map<String, RemoteConnection> mConnectionById = new HashMap<>();
+    private final Set<RemoteConnection> mPendingConnections = new HashSet<>();
+
+    RemoteConnectionService(IConnectionService connectionService) throws RemoteException {
+        mConnectionService = connectionService;
+        mConnectionService.addConnectionServiceAdapter(mServant.getStub());
+        mConnectionService.asBinder().linkToDeath(mDeathRecipient, 0);
     }
 
     @Override
@@ -409,66 +241,37 @@
         return "[RemoteCS - " + mConnectionService.asBinder().toString() + "]";
     }
 
-    /** ${inheritDoc} */
-    @Override
-    public final void binderDied() {
-        if (mConnection != null) {
-            destroyConnection();
-        }
-
-        release();
-    }
-
     final RemoteConnection createRemoteConnection(
             PhoneAccountHandle connectionManagerPhoneAccount,
             ConnectionRequest request,
             boolean isIncoming) {
-        if (mConnectionId == null) {
-            String id = UUID.randomUUID().toString();
-            ConnectionRequest newRequest = new ConnectionRequest(
-                    request.getAccountHandle(),
-                    id,
-                    request.getHandle(),
-                    request.getHandlePresentation(),
-                    request.getExtras(),
-                    request.getVideoState());
-            mConnection = new RemoteConnection(mConnectionService, request, isIncoming);
-            try {
-                mConnectionService.createConnection(
-                        connectionManagerPhoneAccount,
-                        newRequest,
-                        isIncoming);
-                mConnectionId = id;
-            } catch (RemoteException e) {
-                mConnection = RemoteConnection.failure(DisconnectCause.ERROR_UNSPECIFIED,
-                        e.toString());
-            }
-            return mConnection;
-        } else {
-            return RemoteConnection.failure(DisconnectCause.ERROR_UNSPECIFIED, null);
+        ConnectionRequest newRequest = new ConnectionRequest(
+                request.getAccountHandle(),
+                UUID.randomUUID().toString(),
+                request.getHandle(),
+                request.getHandlePresentation(),
+                request.getExtras(),
+                request.getVideoState());
+        try {
+            mConnectionService.createConnection(
+                    connectionManagerPhoneAccount,
+                    newRequest,
+                    isIncoming);
+            RemoteConnection connection =
+                    new RemoteConnection(mConnectionService, request);
+            mPendingConnections.add(connection);
+            mConnectionById.put(newRequest.getCallId(), connection);
+            return connection;
+        } catch (RemoteException e) {
+            return RemoteConnection.failure(DisconnectCause.ERROR_UNSPECIFIED, e.toString());
         }
     }
 
-    /**
-     * Releases the resources associated with this Remote connection service. Should be called when
-     * the remote service is no longer being used.
-     */
-    void release() {
-        mConnectionService.asBinder().unlinkToDeath(this, 0);
-    }
-
-    private boolean isPendingConnection(String id) {
-        return TextUtils.equals(mConnectionId, id);
-    }
-
-    private boolean isCurrentConnection(Object obj) {
-        return obj instanceof String && mConnection != null &&
-                TextUtils.equals(mConnectionId, (String) obj);
-    }
-
-    private void destroyConnection() {
-        mConnection.setDestroyed();
-        mConnection = null;
-        mConnectionId = null;
+    private RemoteConnection findConnectionForAction(String callId, String action) {
+        if (mConnectionById.containsKey(callId)) {
+            return mConnectionById.get(callId);
+        }
+        Log.w(this, "%s - Cannot find Connection %s", action, callId);
+        return NULL_CONNECTION;
     }
 }
diff --git a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
index 60b5e1e..c6f9712 100644
--- a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
@@ -77,5 +77,7 @@
 
     void setCallerDisplayName(String callId, String callerDisplayName, int presentation);
 
+    void setConferenceableConnections(String callId, in List<String> conferenceableCallIds);
+
     void startActivityFromInCall(String callId, in PendingIntent intent);
 }
diff --git a/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
index fc09a3a..8bc950f 100644
--- a/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
@@ -51,7 +51,7 @@
 
     void phoneAccountSelected(String callId, in PhoneAccountHandle accountHandle);
 
-    void conference(String callId);
+    void conference(String callId, String otherCallId);
 
     void splitFromConference(String callId);
 
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index c8c3063..350c27e 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -50,7 +50,8 @@
  * appropriate LISTEN_ flags.
  */
 public class PhoneStateListener {
-    private static final String TAG = "PhoneStateListener";
+    private static final String LOG_TAG = "PhoneStateListener";
+    private static final boolean DBG = false; // STOPSHIP if true
 
     /**
      * Stop listening for updates.
@@ -233,12 +234,14 @@
 
     /** @hide */
     public PhoneStateListener(long subId, Looper looper) {
-        Rlog.d(TAG, "ctor: subId=" + subId + " looper=" + looper);
+        if (DBG) log("ctor: subId=" + subId + " looper=" + looper);
         mSubId = subId;
         mHandler = new Handler(looper) {
             public void handleMessage(Message msg) {
-                Rlog.d(TAG, "mSubId=" + mSubId + " what=0x" + Integer.toHexString(msg.what)
-                 + " msg=" + msg);
+                if (DBG) {
+                    log("mSubId=" + mSubId + " what=0x" + Integer.toHexString(msg.what)
+                            + " msg=" + msg);
+                }
                 switch (msg.what) {
                     case LISTEN_SERVICE_STATE:
                         PhoneStateListener.this.onServiceStateChanged((ServiceState)msg.obj);
@@ -528,4 +531,8 @@
             Message.obtain(mHandler, LISTEN_VOLTE_STATE, 0, 0, lteState).sendToTarget();
         }
     };
+
+    private void log(String s) {
+        Rlog.d(LOG_TAG, s);
+    }
 }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 0772687..c50110a 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2401,7 +2401,7 @@
      *            is sent to the SIM.
      * @param data Data to be sent with the APDU.
      * @return The APDU response from the ICC card with the status appended at
-     *            the end. If an error occurs, an empty string is returned.
+     *            the end.
      */
     public String iccTransmitApduLogicalChannel(int channel, int cla,
             int instruction, int p1, int p2, int p3, String data) {
@@ -2431,7 +2431,7 @@
      *            is sent to the SIM.
      * @param data Data to be sent with the APDU.
      * @return The APDU response from the ICC card with the status appended at
-     *            the end. If an error occurs, an empty string is returned.
+     *            the end.
      */
     public String iccTransmitApduBasicChannel(int cla,
             int instruction, int p1, int p2, int p3, String data) {
diff --git a/telephony/java/com/android/ims/ImsReasonInfo.java b/telephony/java/com/android/ims/ImsReasonInfo.java
index 99faba6..2ab9648 100644
--- a/telephony/java/com/android/ims/ImsReasonInfo.java
+++ b/telephony/java/com/android/ims/ImsReasonInfo.java
@@ -216,9 +216,13 @@
     public static final int CODE_UT_NOT_SUPPORTED = 801;
     public static final int CODE_UT_SERVICE_UNAVAILABLE = 802;
     public static final int CODE_UT_OPERATION_NOT_ALLOWED = 803;
+    public static final int CODE_UT_NETWORK_ERROR = 804;
     public static final int CODE_UT_CB_PASSWORD_MISMATCH = 821;
 
-
+    /**
+     * ECBM
+     */
+    public static final int CODE_ECBM_NOT_SUPPORTED = 901;
 
     // For reason type
     public int mReasonType;
diff --git a/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl
index f36cf39..acd1eb9 100644
--- a/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl
+++ b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl
@@ -96,4 +96,12 @@
      */
     void callSessionUssdMessageReceived(in IImsCallSession session,
             int mode, String ussdMessage);
+
+    /**
+     * Notifies of handover information for this call
+     */
+    void callSessionHandover(in IImsCallSession session,
+            in int srcAccessTech, in int targetAccessTech, in ImsReasonInfo reasonInfo);
+    void callSessionHandoverFailed(in IImsCallSession session,
+            in int srcAccessTech, in int targetAccessTech, in ImsReasonInfo reasonInfo);
 }
diff --git a/telephony/java/com/android/ims/internal/IImsEcbm.aidl b/telephony/java/com/android/ims/internal/IImsEcbm.aidl
new file mode 100644
index 0000000..f890bc2
--- /dev/null
+++ b/telephony/java/com/android/ims/internal/IImsEcbm.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *    * Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *    * Neither the name of The Linux Foundation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.ims.internal;
+
+import com.android.ims.internal.IImsEcbmListener;
+
+/**
+ * Provides the ECBM interface
+ *
+ * {@hide}
+ */
+interface IImsEcbm {
+    /**
+     * Sets the listener.
+     */
+    void setListener(in IImsEcbmListener listener);
+
+    /**
+     * Requests Modem to come out of ECBM mode
+     */
+    void exitEmergencyCallbackMode();
+}
diff --git a/telephony/java/com/android/ims/internal/IImsEcbmListener.aidl b/telephony/java/com/android/ims/internal/IImsEcbmListener.aidl
new file mode 100644
index 0000000..d866ecb
--- /dev/null
+++ b/telephony/java/com/android/ims/internal/IImsEcbmListener.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *    * Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *    * Neither the name of The Linux Foundation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.ims.internal;
+
+/**
+ * A listener type for receiving notifications about the changes to
+ * Emergency Callback Mode through IMS.
+ *
+ * {@hide}
+ */
+interface IImsEcbmListener {
+    /**
+     * Notifies the application when the device enters Emergency Callback Mode.
+     */
+    void enteredECBM();
+
+    /**
+     * Notifies the application when the device exits Emergency Callback Mode.
+     */
+    void exitedECBM();
+}
diff --git a/telephony/java/com/android/ims/internal/IImsService.aidl b/telephony/java/com/android/ims/internal/IImsService.aidl
index 869cd9f..5138305 100644
--- a/telephony/java/com/android/ims/internal/IImsService.aidl
+++ b/telephony/java/com/android/ims/internal/IImsService.aidl
@@ -22,6 +22,7 @@
 import com.android.ims.internal.IImsRegistrationListener;
 import com.android.ims.internal.IImsCallSession;
 import com.android.ims.internal.IImsCallSessionListener;
+import com.android.ims.internal.IImsEcbm;
 import com.android.ims.internal.IImsUt;
 import com.android.ims.internal.IImsConfig;
 
@@ -62,4 +63,11 @@
      * When IMS is OFF, device will behave as CSFB'ed.
      */
     void turnOffIms();
+
+
+    /**
+     * ECBM interface for Emergency Callback mode mechanism.
+     */
+    IImsEcbm getEcbmInterface(int serviceId);
+
 }
diff --git a/telephony/java/com/android/ims/internal/IImsUt.aidl b/telephony/java/com/android/ims/internal/IImsUt.aidl
index f9375e4..50a0169 100644
--- a/telephony/java/com/android/ims/internal/IImsUt.aidl
+++ b/telephony/java/com/android/ims/internal/IImsUt.aidl
@@ -74,7 +74,7 @@
     /**
      * Updates the configuration of the call barring.
      */
-    int updateCallBarring(int cbType, boolean enable);
+    int updateCallBarring(int cbType, boolean enable, in String[] barrList);
 
     /**
      * Updates the configuration of the call forward.
diff --git a/telephony/java/com/android/ims/internal/IImsUtListener.aidl b/telephony/java/com/android/ims/internal/IImsUtListener.aidl
index 3f1b5a7..6416631 100644
--- a/telephony/java/com/android/ims/internal/IImsUtListener.aidl
+++ b/telephony/java/com/android/ims/internal/IImsUtListener.aidl
@@ -21,6 +21,7 @@
 import com.android.ims.ImsCallForwardInfo;
 import com.android.ims.ImsSsInfo;
 import com.android.ims.internal.IImsUt;
+import com.android.ims.ImsReasonInfo;
 
 /**
  * {@hide}
@@ -30,13 +31,13 @@
      * Notifies the result of the supplementary service configuration udpate.
      */
     void utConfigurationUpdated(in IImsUt ut, int id);
-    void utConfigurationUpdateFailed(in IImsUt ut, int id, int errorCode);
+    void utConfigurationUpdateFailed(in IImsUt ut, int id, in ImsReasonInfo error);
 
     /**
      * Notifies the result of the supplementary service configuration query.
      */
     void utConfigurationQueried(in IImsUt ut, int id, in Bundle ssInfo);
-    void utConfigurationQueryFailed(in IImsUt ut, int id, int errorCode);
+    void utConfigurationQueryFailed(in IImsUt ut, int id, in ImsReasonInfo error);
 
     /**
      * Notifies the status of the call barring supplementary service.
diff --git a/telephony/java/com/android/internal/telephony/IMms.aidl b/telephony/java/com/android/internal/telephony/IMms.aidl
index 30ef725..cbcef25 100644
--- a/telephony/java/com/android/internal/telephony/IMms.aidl
+++ b/telephony/java/com/android/internal/telephony/IMms.aidl
@@ -31,11 +31,14 @@
      * @param callingPkg the package name of the calling app
      * @param pdu the MMS message encoded in standard MMS PDU format
      * @param locationUrl the optional location url for where this message should be sent to
+     * @param configOverrides the carrier-specific messaging configuration values to override for
+     *  sending the message. See {@link android.telephony.MessagingConfigurationManager} for the
+     *  value names and types.
      * @param sentIntent if not NULL this <code>PendingIntent</code> is
      *  broadcast when the message is successfully sent, or failed
      */
     void sendMessage(long subId, String callingPkg, in byte[] pdu, String locationUrl,
-            in PendingIntent sentIntent);
+            in ContentValues configOverrides, in PendingIntent sentIntent);
 
     /**
      * Download an MMS message using known location and transaction id
@@ -44,11 +47,14 @@
      * @param callingPkg the package name of the calling app
      * @param locationUrl the location URL of the MMS message to be downloaded, usually obtained
      *  from the MMS WAP push notification
+     * @param configOverrides the carrier-specific messaging configuration values to override for
+     *  downloading the message. See {@link android.telephony.MessagingConfigurationManager} for the
+     *  value names and types.
      * @param downloadedIntent if not NULL this <code>PendingIntent</code> is
      *  broadcast when the message is downloaded, or the download is failed
      */
     void downloadMessage(long subId, String callingPkg, String locationUrl,
-            in PendingIntent downloadedIntent);
+            in ContentValues configOverrides, in PendingIntent downloadedIntent);
 
     /**
      * Update the status of a pending (send-by-IP) MMS message handled by the carrier app.
@@ -75,53 +81,30 @@
      * Get carrier-dependent configuration value as boolean. For example, if multipart SMS
      * is supported.
      *
+     * @param subId the SIM id
      * @param name the configuration name
      * @param defaultValue the default value if fail to find the name
      */
-    boolean getCarrierConfigBoolean(String name, boolean defaultValue);
+    boolean getCarrierConfigBoolean(long subId, String name, boolean defaultValue);
 
     /**
      * Get carrier-dependent configuration value as int. For example, the MMS message size limit.
      *
+     * @param subId the SIM id
      * @param name the configuration name
      * @param defaultValue the default value if fail to find the name
      */
-    int getCarrierConfigInt(String name, int defaultValue);
+    int getCarrierConfigInt(long subId, String name, int defaultValue);
 
     /**
      * Get carrier-dependent configuration value as String. For example, extra HTTP headers for
      * MMS request.
      *
+     * @param subId the SIM id
      * @param name the configuration name
      * @param defaultValue the default value if fail to find the name
      */
-    String getCarrierConfigString(String name, String defaultValue);
-
-    /**
-     * Set carrier-dependent configuration value as boolean. For example, if multipart SMS
-     * is supported.
-     *
-     * @param name the configuration name
-     * @param value the configuration value
-     */
-    void setCarrierConfigBoolean(String callingPkg, String name, boolean value);
-
-    /**
-     * Set carrier-dependent configuration value as int. For example, the MMS message size limit.
-     *
-     * @param name the configuration name
-     * @param value the configuration value
-     */
-    void setCarrierConfigInt(String callingPkg, String name, int value);
-
-    /**
-     * Set carrier-dependent configuration value as String. For example, extra HTTP headers for
-     * MMS request.
-     *
-     * @param name the configuration name
-     * @param value the configuration value
-     */
-    void setCarrierConfigString(String callingPkg, String name, String value);
+    String getCarrierConfigString(long subId, String name, String defaultValue);
 
     /**
      * Import a text message into system's SMS store
@@ -220,11 +203,14 @@
      * @param subId the SIM id
      * @param callingPkg the package name of the calling app
      * @param messageUri the URI of the stored message
+     * @param configOverrides the carrier-specific messaging configuration values to override for
+     *  sending the message. See {@link android.telephony.MessagingConfigurationManager} for the
+     *  value names and types.
      * @param sentIntent if not NULL this <code>PendingIntent</code> is
      *  broadcast when the message is successfully sent, or failed
      */
     void sendStoredMessage(long subId, String callingPkg, in Uri messageUri,
-            in PendingIntent sentIntent);
+            in ContentValues configOverrides, in PendingIntent sentIntent);
 
     /**
      * Turns on/off the flag to automatically write sent/received SMS/MMS messages into system
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 72b04cf..d256f9d 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -530,7 +530,7 @@
      *            is sent to the SIM.
      * @param data Data to be sent with the APDU.
      * @return The APDU response from the ICC card with the status appended at
-     *            the end. If an error occurs, an empty string is returned.
+     *            the end.
      */
     String iccTransmitApduLogicalChannel(int channel, int cla, int instruction,
             int p1, int p2, int p3, String data);
@@ -548,7 +548,7 @@
      *            is sent to the SIM.
      * @param data Data to be sent with the APDU.
      * @return The APDU response from the ICC card with the status appended at
-     *            the end. If an error occurs, an empty string is returned.
+     *            the end.
      */
     String iccTransmitApduBasicChannel(int cla, int instruction,
             int p1, int p2, int p3, String data);
diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
index 5ec4247..41b6b76 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
@@ -209,4 +209,14 @@
      * Set to the sim count.
      */
     static final String PROPERTY_SIM_COUNT = "ro.telephony.sim.count";
+
+    /**
+     * Enable VoLTE/VT over IMS: debug option
+     * If 1: use IMS if provisioned/registered etc (i.e. standard operation)
+     * If 0: use CS.
+     * If missing: use PROPERTY_DBG_IMS_VOLTE_ENABLE_DEAFULT
+     */
+    static final String PROPERTY_DBG_IMS_VOLTE_ENABLE = "persist.dbg.ims_volte_enable";
+
+    static final int PROPERTY_DBG_IMS_VOLTE_ENABLE_DEAFULT = 0;
 }
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index 8a2732d..46c81b6 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -572,6 +572,13 @@
 
     /** {@hide} */
     @Override
+    public Context createApplicationContext(ApplicationInfo application, int flags)
+            throws PackageManager.NameNotFoundException {
+        return null;
+    }
+
+    /** {@hide} */
+    @Override
     public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
             throws PackageManager.NameNotFoundException {
         throw new UnsupportedOperationException();
@@ -595,7 +602,7 @@
 
     @Override
     public boolean isRestricted() {
-        throw new UnsupportedOperationException();        
+        throw new UnsupportedOperationException();
     }
 
     /** @hide */
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 8ce7888..c84f40e 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -772,6 +772,15 @@
     /**
      * @hide
      */
+    @Override
+    public void removeCrossProfileIntentsForPackage(String packageName, int sourceUserId,
+            int targetUserId) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
     public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
         throw new UnsupportedOperationException();
     }
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerController.java b/tests/OneMedia/src/com/android/onemedia/PlayerController.java
index 3686899..c0799fc 100644
--- a/tests/OneMedia/src/com/android/onemedia/PlayerController.java
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerController.java
@@ -193,8 +193,7 @@
             if (metadata == null) {
                 return;
             }
-            Log.d(TAG, "Received metadata change, title is "
-                    + metadata.getString(MediaMetadata.METADATA_KEY_TITLE));
+            Log.d(TAG, "Received metadata change, " + metadata.getDescription());
         }
     }
 
diff --git a/tests/SoundTriggerTests/src/android/hardware/soundtrigger/SoundTriggerTest.java b/tests/SoundTriggerTests/src/android/hardware/soundtrigger/SoundTriggerTest.java
index 4372ff9..65a3d8a 100644
--- a/tests/SoundTriggerTests/src/android/hardware/soundtrigger/SoundTriggerTest.java
+++ b/tests/SoundTriggerTests/src/android/hardware/soundtrigger/SoundTriggerTest.java
@@ -23,6 +23,7 @@
 import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra;
 import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
 import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent;
+import android.media.AudioFormat;
 import android.os.Parcel;
 import android.test.InstrumentationTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
@@ -97,7 +98,8 @@
         Keyphrase[] keyphrases = new Keyphrase[2];
         keyphrases[0] = new Keyphrase(1, 0, "en-US", "hello", new int[] {0});
         keyphrases[1] = new Keyphrase(2, 0, "fr-FR", "there", new int[] {1, 2});
-        KeyphraseSoundModel ksm = new KeyphraseSoundModel(UUID.randomUUID(), null, keyphrases);
+        KeyphraseSoundModel ksm = new KeyphraseSoundModel(UUID.randomUUID(), UUID.randomUUID(),
+                null, keyphrases);
 
         // Write to a parcel
         Parcel parcel = Parcel.obtain();
@@ -119,8 +121,8 @@
         Keyphrase[] keyphrases = new Keyphrase[2];
         keyphrases[0] = new Keyphrase(1, 0, "en-US", "hello", new int[] {0});
         keyphrases[1] = new Keyphrase(2, 0, "fr-FR", "there", new int[] {1, 2});
-        KeyphraseSoundModel ksm = new KeyphraseSoundModel(UUID.randomUUID(), new byte[0],
-                keyphrases);
+        KeyphraseSoundModel ksm = new KeyphraseSoundModel(UUID.randomUUID(), UUID.randomUUID(),
+                new byte[0], keyphrases);
 
         // Write to a parcel
         Parcel parcel = Parcel.obtain();
@@ -141,7 +143,8 @@
     public void testKeyphraseSoundModelParcelUnparcel_noKeyphrases() throws Exception {
         byte[] data = new byte[10];
         mRandom.nextBytes(data);
-        KeyphraseSoundModel ksm = new KeyphraseSoundModel(UUID.randomUUID(), data, null);
+        KeyphraseSoundModel ksm = new KeyphraseSoundModel(UUID.randomUUID(), UUID.randomUUID(),
+                data, null);
 
         // Write to a parcel
         Parcel parcel = Parcel.obtain();
@@ -162,8 +165,8 @@
     public void testKeyphraseSoundModelParcelUnparcel_zeroKeyphrases() throws Exception {
         byte[] data = new byte[10];
         mRandom.nextBytes(data);
-        KeyphraseSoundModel ksm = new KeyphraseSoundModel(UUID.randomUUID(), data,
-                new Keyphrase[0]);
+        KeyphraseSoundModel ksm = new KeyphraseSoundModel(UUID.randomUUID(), UUID.randomUUID(),
+                data, new Keyphrase[0]);
 
         // Write to a parcel
         Parcel parcel = Parcel.obtain();
@@ -187,7 +190,8 @@
         keyphrases[1] = new Keyphrase(2, 0, "fr-FR", "there", new int[] {1, 2});
         byte[] data = new byte[200 * 1024];
         mRandom.nextBytes(data);
-        KeyphraseSoundModel ksm = new KeyphraseSoundModel(UUID.randomUUID(), data, keyphrases);
+        KeyphraseSoundModel ksm = new KeyphraseSoundModel(UUID.randomUUID(), UUID.randomUUID(),
+                data, keyphrases);
 
         // Write to a parcel
         Parcel parcel = Parcel.obtain();
@@ -207,7 +211,7 @@
     @SmallTest
     public void testRecognitionEventParcelUnparcel_noData() throws Exception {
         RecognitionEvent re = new RecognitionEvent(SoundTrigger.RECOGNITION_STATUS_SUCCESS, 1,
-                true, 2, 3, 4, null);
+                true, 2, 3, 4, false, null, null);
 
         // Write to a parcel
         Parcel parcel = Parcel.obtain();
@@ -224,7 +228,7 @@
     @SmallTest
     public void testRecognitionEventParcelUnparcel_zeroData() throws Exception {
         RecognitionEvent re = new RecognitionEvent(SoundTrigger.RECOGNITION_STATUS_FAILURE, 1,
-                true, 2, 3, 4, new byte[1]);
+                true, 2, 3, 4, false, null, new byte[1]);
 
         // Write to a parcel
         Parcel parcel = Parcel.obtain();
@@ -243,7 +247,32 @@
         byte[] data = new byte[200 * 1024];
         mRandom.nextBytes(data);
         RecognitionEvent re = new RecognitionEvent(SoundTrigger.RECOGNITION_STATUS_ABORT, 1,
-                false, 2, 3, 4, data);
+                false, 2, 3, 4, false, null, data);
+
+        // Write to a parcel
+        Parcel parcel = Parcel.obtain();
+        re.writeToParcel(parcel, 0);
+
+        // Read from it
+        parcel.setDataPosition(0);
+        RecognitionEvent unparceled = RecognitionEvent.CREATOR.createFromParcel(parcel);
+
+        // Verify that they are the same
+        assertEquals(re, unparceled);
+    }
+
+    @SmallTest
+    public void testRecognitionEventParcelUnparcel_largeAudioData() throws Exception {
+        byte[] data = new byte[200 * 1024];
+        mRandom.nextBytes(data);
+        RecognitionEvent re = new RecognitionEvent(SoundTrigger.RECOGNITION_STATUS_ABORT, 1,
+                false, 2, 3, 4, true,
+                (new AudioFormat.Builder())
+                .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
+                .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
+                .setSampleRate(16000)
+                .build(),
+                data);
 
         // Write to a parcel
         Parcel parcel = Parcel.obtain();
@@ -260,7 +289,7 @@
     @SmallTest
     public void testKeyphraseRecognitionEventParcelUnparcel_noKeyphrases() throws Exception {
         KeyphraseRecognitionEvent re = new KeyphraseRecognitionEvent(
-                SoundTrigger.RECOGNITION_STATUS_SUCCESS, 1, true, 2, 3, 4, null, false, null);
+                SoundTrigger.RECOGNITION_STATUS_SUCCESS, 1, true, 2, 3, 4, false, null, null, null);
 
         // Write to a parcel
         Parcel parcel = Parcel.obtain();
@@ -279,8 +308,8 @@
     public void testKeyphraseRecognitionEventParcelUnparcel_zeroData() throws Exception {
         KeyphraseRecognitionExtra[] kpExtra = new KeyphraseRecognitionExtra[0];
         KeyphraseRecognitionEvent re = new KeyphraseRecognitionEvent(
-                SoundTrigger.RECOGNITION_STATUS_FAILURE, 2, true, 2, 3, 4, new byte[1],
-                true, kpExtra);
+                SoundTrigger.RECOGNITION_STATUS_FAILURE, 2, true, 2, 3, 4, false, null, new byte[1],
+                kpExtra);
 
         // Write to a parcel
         Parcel parcel = Parcel.obtain();
@@ -303,20 +332,20 @@
         ConfidenceLevel cl1 = new ConfidenceLevel(1, 90);
         ConfidenceLevel cl2 = new ConfidenceLevel(2, 30);
         kpExtra[0] = new KeyphraseRecognitionExtra(1,
-                SoundTrigger.RECOGNITION_MODE_USER_IDENTIFICATION,
+                SoundTrigger.RECOGNITION_MODE_USER_IDENTIFICATION, 0,
                 new ConfidenceLevel[] {cl1, cl2});
         kpExtra[1] = new KeyphraseRecognitionExtra(1,
-                SoundTrigger.RECOGNITION_MODE_VOICE_TRIGGER,
+                SoundTrigger.RECOGNITION_MODE_VOICE_TRIGGER, 0,
                 new ConfidenceLevel[] {cl2});
         kpExtra[2] = new KeyphraseRecognitionExtra(1,
-                SoundTrigger.RECOGNITION_MODE_VOICE_TRIGGER, null);
+                SoundTrigger.RECOGNITION_MODE_VOICE_TRIGGER, 0, null);
         kpExtra[3] = new KeyphraseRecognitionExtra(1,
-                SoundTrigger.RECOGNITION_MODE_VOICE_TRIGGER,
+                SoundTrigger.RECOGNITION_MODE_VOICE_TRIGGER, 0,
                 new ConfidenceLevel[0]);
 
         KeyphraseRecognitionEvent re = new KeyphraseRecognitionEvent(
-                SoundTrigger.RECOGNITION_STATUS_FAILURE, 1, true, 2, 3, 4, data,
-                false, kpExtra);
+                SoundTrigger.RECOGNITION_STATUS_FAILURE, 1, true, 2, 3, 4, false, null, data,
+                kpExtra);
 
         // Write to a parcel
         Parcel parcel = Parcel.obtain();
diff --git a/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java b/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java
index 9c2cf41..78d4f96 100644
--- a/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java
+++ b/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java
@@ -67,13 +67,18 @@
         IDelegate delegate = LittleMock.mock(IDelegate.class);
         MockableTextToSpeechService.setMocker(delegate);
 
+        LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE).when(delegate).onIsLanguageAvailable(
+                "eng", "USA", "variant");
+        LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE).when(delegate).onLoadLanguage(
+                "eng", "USA", "variant");
+
         // Test 1 :Tests that calls to onLoadLanguage( ) are delegated through to the
         // service without any caching or intermediate steps.
-        mTts.setLanguage(new Locale("eng", "USA", "variant"));
-        LittleMock.verify(delegate, LittleMock.times(1)).onIsLanguageAvailable(
-                "eng", "USA", "variant");
+        assertEquals(TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE, mTts.setLanguage(new Locale("eng", "USA", "variant")));
+        LittleMock.verify(delegate, LittleMock.anyTimes()).onIsLanguageAvailable(
+            "eng", "USA", "variant");
         LittleMock.verify(delegate, LittleMock.times(1)).onLoadLanguage(
-                "eng", "USA", "variant");
+            "eng", "USA", "variant");
     }
 
     public void testSetLanguage_availableLanguage() throws Exception {
@@ -86,8 +91,10 @@
         // request language changes from that point on.
         LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onIsLanguageAvailable(
                 "eng", "USA", "variant");
+        LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onIsLanguageAvailable(
+                "eng", "USA", "");
         LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onLoadLanguage(
-                "eng", "USA", "variant");
+                "eng", "USA", "");
         mTts.setLanguage(new Locale("eng", "USA", "variant"));
         blockingCallSpeak("foo bar", delegate);
         ArgumentCaptor<SynthesisRequest> req = LittleMock.createCaptor();
@@ -97,6 +104,7 @@
         assertEquals("eng", req.getValue().getLanguage());
         assertEquals("USA", req.getValue().getCountry());
         assertEquals("", req.getValue().getVariant());
+        assertEquals("en-US", req.getValue().getVoiceName());
     }
 
     public void testSetLanguage_unavailableLanguage() throws Exception {
@@ -120,6 +128,7 @@
         assertEquals("eng", req2.getValue().getLanguage());
         assertEquals("USA", req2.getValue().getCountry());
         assertEquals("", req2.getValue().getVariant());
+        assertEquals("en-US", req2.getValue().getVoiceName());
     }
 
     public void testIsLanguageAvailable() {
@@ -135,6 +144,28 @@
                 "eng", "USA", "");
     }
 
+    public void testDefaultLanguage_setsVoiceName() throws Exception {
+        IDelegate delegate = LittleMock.mock(IDelegate.class);
+        MockableTextToSpeechService.setMocker(delegate);
+
+        // ---------------------------------------------------------
+        // Test that default language also sets the default voice
+        // name
+        LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onIsLanguageAvailable(
+            LittleMock.anyString(), LittleMock.anyString(), LittleMock.anyString());
+        LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onLoadLanguage(
+            LittleMock.anyString(), LittleMock.anyString(), LittleMock.anyString());
+        blockingCallSpeak("foo bar", delegate);
+        ArgumentCaptor<SynthesisRequest> req = LittleMock.createCaptor();
+        LittleMock.verify(delegate, LittleMock.times(1)).onSynthesizeText(req.capture(),
+                LittleMock.<SynthesisCallback>anyObject());
+
+        Locale defaultLocale = Locale.getDefault();
+        assertEquals(defaultLocale.getISO3Language(), req.getValue().getLanguage());
+        assertEquals(defaultLocale.getISO3Country(), req.getValue().getCountry());
+        assertEquals("", req.getValue().getVariant());
+        assertEquals(defaultLocale.toLanguageTag(), req.getValue().getVoiceName());
+    }
 
     private void blockingCallSpeak(String speech, IDelegate mock) throws
             InterruptedException {
diff --git a/tests/VectorDrawableTest/res/anim/animation_linear_progress_bar_rect1_scale.xml b/tests/VectorDrawableTest/res/anim/animation_linear_progress_bar_rect1_scale.xml
new file mode 100644
index 0000000..7347220
--- /dev/null
+++ b/tests/VectorDrawableTest/res/anim/animation_linear_progress_bar_rect1_scale.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <objectAnimator
+        android:duration="2016"
+        android:pathData="
+        M 0.1 1 l 0 0 l 0.00882427215576 0 l 0.00982859611511 0 l 0.01086503982544 0 l 0.01193084716797 0 l 0.0130220413208 0 l 0.01413340568542 0 l 0.01525821685791 0 l 0.01638801574707 0 l 0.01751272201538 0 l 0.01862035751343 0 l 0.01969732284546 0 l 0.02072854995728 0 l 0.02169786453247 0 l 0.02258871078491 0 l 0.02338474273682 0 l 0.02407070159912 0 l 0.02463348388672 0 l 0.0250626373291 0 l 0.02535140991211 0 l 0.02549694061279 0 l 0.02550048828125 0 l 0.02536708831787 0 l 0.02510528564453 0 l 0.02472625732422 0 l 0.0242431640625 0 l 0.02367015838623 0 l 0.02302188873291 0 l 0.02231246948242 0 l 0.02155555725098 0 l 0.02076324462891 0 l 0.01994682312012 0 l 0.01911575317383 0 l 0.01827827453613 0 l 0.01732414245605 0 l 0.01522109985352 0 l 0.01262580871582 0 l 0.00973388671875 0 l 0.00647575378418 0 l 0.0027661895752 0 l -0.00149223327637 0 l -0.00639404296875 0 l -0.01199066162109 0 l -0.01820671081543 0 l -0.02470901489258 0 l -0.03080444335937 0 l -0.0355574798584 0 l -0.03823974609375 0 l -0.03876884460449 0 l -0.03766212463379 0 l -0.03562252044678 0 l -0.03321434020996 0 l -0.03078151702881 0 l -0.02849582672119 0 l -0.02642543792725 0 l -0.02458423614502 0 l -0.02296115875244 0 l -0.02153518676758 0 l -0.02028285980225 0 l -0.01918155670166 0 l -0.01821084976196 0 l -0.01735286712646 0 l -0.01659231185913 0 l -0.01591604232788 0 l -0.0153129196167 0 l -0.01477350234985 0 l -0.01413362503052 0 l -0.01339265823364 0 l -0.01270362854004 0 l -0.01206108093262 0 l -0.01146033287048 0 l -0.01089729309082 0 l -0.01036835670471 0 l -0.00987038612366 0 l -0.00940062522888 0 l -0.00895661354065 0 l -0.00853617668152 0"
+        android:propertyXName="scaleX"
+        android:repeatCount="-1" />
+
+</set>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/anim/animation_linear_progress_bar_rect1_translate.xml b/tests/VectorDrawableTest/res/anim/animation_linear_progress_bar_rect1_translate.xml
new file mode 100644
index 0000000..4781ba8
--- /dev/null
+++ b/tests/VectorDrawableTest/res/anim/animation_linear_progress_bar_rect1_translate.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <objectAnimator
+        android:duration="2016"
+        android:pathData="
+        M -522.599975585938 0 l 0 0 l 0.12939453125 0 l 0.33831787109375 0 l 0.55450439453125 0 l 0.7708740234375 0 l 0.98065185546875 0 l 1.1964111328125 0 l 1.41351318359375 0 l 1.63153076171875 0 l 1.85052490234375 0 l 2.07052612304688 0 l 2.29080200195312 0 l 2.51150512695312 0 l 2.73260498046875 0 l 2.95355224609375 0 l 3.17404174804688 0 l 3.39422607421875 0 l 3.61355590820312 0 l 3.83163452148438 0 l 4.04849243164062 0 l 4.263671875 0 l 5.74725341796875 0 l 6.1026611328125 0 l 6.45980834960938 0 l 6.81781005859375 0 l 7.17654418945312 0 l 7.53366088867188 0 l 7.88861083984375 0 l 8.23974609375 0 l 8.58447265625 0 l 8.92156982421875 0 l 9.24810791015625 0 l 9.56137084960938 0 l 9.85906982421875 0 l 10.1377868652344 0 l 10.3955688476562 0 l 10.6287536621094 0 l 10.8357238769531 0 l 11.0149230957031 0 l 11.1639709472656 0 l 11.2832336425781 0 l 11.3713989257812 0 l 11.4301147460938 0 l 11.4596557617188 0 l 11.4611053466797 0 l 11.4369049072266 0 l 11.3887786865234 0 l 11.3183441162109 0 l 11.2276000976562 0 l 11.1185607910156 0 l 10.9933776855469 0 l 10.8534698486328 0 l 10.6995391845703 0 l 10.533935546875 0 l 10.3744659423828 0 l 10.3707733154297 0 l 10.4309463500977 0 l 10.5275726318359 0 l 10.671501159668 0 l 10.8763961791992 0 l 11.1566543579102 0 l 11.5270767211914 0 l 11.9947967529297 0 l 12.5502433776855 0 l 13.1453399658203 0 l 13.680793762207 0 l 14.0223298072815 0 l 14.0650296211243 0 l 13.798041343689 0 l 13.2949924468994 0 l 12.6584892272949 0 l 11.9693031311035 0 l 11.2772979736328 0 l 10.607666015625 0 l 9.97052764892578 0 l 9.36723327636719 0 l 8.79751586914062 0 l 8.25792694091797 0 l 7.74495697021484 0 l 7.25632476806641 0 l 6.78855895996094 0 l 6.33934020996094 0 l 5.9071044921875 0 l 5.48941040039062 0 l 5.08502197265625 0 l 4.69291687011719 0 l 4.33430480957031 0 l 4.00733947753906 0 l 3.68829345703125 0 l 3.37684631347656 0 l 3.07246398925781 0 l 2.77439880371094 0 l 2.48252868652344 0 l 2.20101928710938 0 l 1.91748046875 0 l 1.63726806640625 0 l 1.36772155761719 0"
+        android:propertyXName="translateX"
+        android:repeatCount="-1" />
+
+</set>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/anim/animation_linear_progress_bar_rect2_scale.xml b/tests/VectorDrawableTest/res/anim/animation_linear_progress_bar_rect2_scale.xml
new file mode 100644
index 0000000..a61af8f
--- /dev/null
+++ b/tests/VectorDrawableTest/res/anim/animation_linear_progress_bar_rect2_scale.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <objectAnimator
+        android:duration="2016"
+        android:pathData="
+        M 0.1 1 l 0.00930031776428 0 l 0.01123028755188 0 l 0.01313143730164 0 l 0.01497107505798 0 l 0.01671510696411 0 l 0.01833034515381 0 l 0.01978672027588 0 l 0.02105976104736 0 l 0.02213228225708 0 l 0.02299520492554 0 l 0.02364795684814 0 l 0.02409727096558 0 l 0.02435619354248 0 l 0.02444213867188 0 l 0.02437515258789 0 l 0.02417644500732 0 l 0.02386695861816 0 l 0.02346652984619 0 l 0.02299335479736 0 l 0.0224634552002 0 l 0.02189086914062 0 l 0.02128746032715 0 l 0.02066318511963 0 l 0.02002624511719 0 l 0.01938335418701 0 l 0.01873977661133 0 l 0.01809989929199 0 l 0.01746696472168 0 l 0.01684349060059 0 l 0.01623161315918 0 l 0.0156324005127 0 l 0.0150471496582 0 l 0.01447631835938 0 l 0.01392051696777 0 l 0.01337966918945 0 l 0.0128540802002 0 l 0.01234344482422 0 l 0.01184753417969 0 l 0.0113663482666 0 l 0.01089920043945 0 l 0.01044593811035 0 l 0.00998542785645 0 l 0.00933837890625 0 l 0.00863349914551 0 l 0.00791206359863 0 l 0.00717010498047 0 l 0.00640274047852 0 l 0.00560478210449 0 l 0.00477012634277 0 l 0.00389221191406 0 l 0.00296325683594 0 l 0.0019751739502 0 l 0.00091903686523 0 l -0.00021408081055 0 l -0.00143287658691 0 l -0.00274444580078 0 l -0.00415267944336 0 l -0.00565589904785 0 l -0.00724327087402 0 l -0.00889205932617 0 l -0.01056480407715 0 l -0.01220878601074 0 l -0.01376045227051 0 l -0.01515449523926 0 l -0.01633560180664 0 l -0.01726905822754 0 l -0.01794639587402 0 l -0.0183829498291 0 l -0.01861137390137 0 l -0.01867179870605 0 l -0.01860504150391 0 l -0.01844764709473 0 l -0.01822959899902 0 l -0.01797431945801 0 l -0.0176993560791 0 l -0.0174169921875 0 l -0.01713603973389 0 l -0.01686214447021 0 l -0.01651359558105 0 l -0.01609485626221 0 l -0.01569358825684 0 l -0.01531024932861 0 l -0.0149446105957 0 l -0.01459632873535 0 l -0.01426464080811 0 l -0.0139489364624 0 l -0.01364833831787 0 l -0.01336200714111 0 l -0.01308917999268 0 l -0.01282897949219 0 l -0.01258075714111 0 l -0.01234363555908 0 l -0.01211700439453 0 l -0.01190029144287 0 l -0.01169273376465 0 l -0.01149394989014 0 l -0.01130325317383 0 l -0.01112024307251 0 l -0.01094444274902 0 l -0.01077545166016 0 l -0.0106128692627 0 l -0.01045631408691 0 l -0.01030544281006 0 l -0.01016000747681 0 l -0.01001962661743 0 l -0.0098840713501 0 l -0.00975311279297 0 l -0.00962644577026 0 l -0.00950393676758 0 l -0.00938529968262 0 l -0.00927038192749 0 l -0.00915899276733 0 l -0.00905097961426 0 l -0.00894614219666 0 l -0.00884438514709 0 l -0.00874552726746 0 l -0.00864946365356 0 l -0.00855606079102 0 l -0.00846519470215 0 l -0.00837676048279 0 "
+        android:propertyXName="scaleX"
+        android:repeatCount="-1" />
+
+</set>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/anim/animation_linear_progress_bar_rect2_translate.xml b/tests/VectorDrawableTest/res/anim/animation_linear_progress_bar_rect2_translate.xml
new file mode 100644
index 0000000..31fa795
--- /dev/null
+++ b/tests/VectorDrawableTest/res/anim/animation_linear_progress_bar_rect2_translate.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <objectAnimator
+        android:duration="2016"
+        android:pathData="
+        M -197.600006103516 0 l 1.42625427246094 0 l 1.80754089355469 0 l 2.18778991699219 0 l 2.56109619140625 0 l 2.91810607910156 0 l 3.25482177734375 0 l 3.57159423828125 0 l 3.862548828125 0 l 4.12493896484375 0 l 4.35758972167969 0 l 4.56034851074219 0 l 4.73426818847656 0 l 4.88090515136719 0 l 5.00271606445312 0 l 5.10273742675781 0 l 5.18400573730469 0 l 5.24911499023438 0 l 5.30097961425781 0 l 5.34226226806641 0 l 5.37535095214844 0 l 5.40180206298828 0 l 5.42322540283203 0 l 5.44123077392578 0 l 5.45704650878906 0 l 5.47099304199219 0 l 5.48395538330078 0 l 5.4967041015625 0 l 5.50949859619141 0 l 5.52214813232422 0 l 5.53528594970703 0 l 5.54912567138672 0 l 5.56306457519531 0 l 5.57742691040039 0 l 5.59244155883789 0 l 5.60744094848633 0 l 5.62243270874023 0 l 5.6376781463623 0 l 5.65262794494629 0 l 5.66689777374268 0 l 5.68069934844971 0 l 5.69401162862778 0 l 5.70898681879044 0 l 5.75169992446899 0 l 5.80327129364014 0 l 5.85710144042969 0 l 5.91399765014648 0 l 5.97450065612793 0 l 6.03849411010742 0 l 6.10729217529297 0 l 6.18125534057617 0 l 6.26116561889648 0 l 6.34840393066406 0 l 6.44406127929688 0 l 6.54866790771484 0 l 6.66371917724609 0 l 6.79020690917969 0 l 6.92859649658203 0 l 7.07807159423828 0 l 7.23712158203125 0 l 7.40253448486328 0 l 7.56884765625 0 l 7.72840881347656 0 l 7.87199401855469 0 l 7.98992919921875 0 l 8.07417297363281 0 l 8.12013244628906 0 l 8.12655639648438 0 l 8.09510803222656 0 l 8.03091430664062 0 l 7.93995666503906 0 l 7.827880859375 0 l 7.69976806640625 0 l 7.56065368652344 0 l 7.41322326660156 0 l 7.26063537597656 0 l 7.10470581054688 0 l 6.94624328613281 0 l 6.78694152832031 0 l 6.6390380859375 0 l 6.50302124023438 0 l 6.36688232421875 0 l 6.23043823242188 0 l 6.09356689453125 0 l 5.95706176757812 0 l 5.82064819335938 0 l 5.6839599609375 0 l 5.5477294921875 0 l 5.41143798828125 0 l 5.27532958984375 0 l 5.13922119140625 0 l 5.00347900390625 0 l 4.8680419921875 0 l 4.73251342773438 0 l 4.59732055664062 0 l 4.46258544921875 0 l 4.328125 0 l 4.1937255859375 0 l 4.0599365234375 0 l 3.92672729492188 0 l 3.79376220703125 0 l 3.66119384765625 0 l 3.52935791015625 0 l 3.398193359375 0 l 3.26748657226562 0 l 3.13726806640625 0 l 3.00796508789062 0 l 2.87939453125 0 l 2.7515869140625 0 l 2.62445068359375 0 l 2.49810791015625 0 l 2.3726806640625 0 l 2.2481689453125 0 l 2.12457275390625 0 l 2.00173950195312 0 l 1.87997436523438 0 l 1.7618408203125 0 l 1.64154052734375 0 l 1.51962280273438 0 l 1.40017700195312 0 l 1.28421020507812 0 "
+        android:propertyXName="translateX"
+        android:repeatCount="-1" />
+
+</set>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/animation_vector_linear_progress_bar.xml b/tests/VectorDrawableTest/res/drawable/animation_vector_linear_progress_bar.xml
new file mode 100644
index 0000000..05bf833
--- /dev/null
+++ b/tests/VectorDrawableTest/res/drawable/animation_vector_linear_progress_bar.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/vector_drawable_linear_progress_bar" >
+
+    <target
+        android:name="path1"
+        android:animation="@anim/animation_linear_progress_bar_rect1_translate" />
+    <target
+        android:name="path1"
+        android:animation="@anim/animation_linear_progress_bar_rect1_scale" />
+
+    <target
+        android:name="path2"
+        android:animation="@anim/animation_linear_progress_bar_rect2_translate" />
+    <target
+        android:name="path2"
+        android:animation="@anim/animation_linear_progress_bar_rect2_scale" />
+</animated-vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable26.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable26.xml
new file mode 100644
index 0000000..29cff52
--- /dev/null
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable26.xml
@@ -0,0 +1,45 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="64dp"
+    android:viewportHeight="200"
+    android:viewportWidth="200"
+    android:width="64dp" >
+
+    <group>
+        <path
+            android:name="background1"
+            android:fillColor="#FF000000"
+            android:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z" />
+        <path
+            android:name="background2"
+            android:fillColor="#FF000000"
+            android:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z" />
+    </group>
+    <group
+        android:translateX="50"
+        android:translateY="50" >
+        <path
+            android:name="twoLines"
+            android:pathData="M 100,20 l 0 80 l -30 -80"
+            android:strokeColor="#FF00FF00"
+            android:strokeLineCap="butt"
+            android:strokeLineJoin="miter"
+            android:strokeMiterLimit="5"
+            android:strokeWidth="20" />
+    </group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable27.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable27.xml
new file mode 100644
index 0000000..b0f0cee
--- /dev/null
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable27.xml
@@ -0,0 +1,45 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="64dp"
+    android:viewportHeight="200"
+    android:viewportWidth="200"
+    android:width="64dp" >
+
+    <group>
+        <path
+            android:name="background1"
+            android:fillColor="#FF000000"
+            android:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z" />
+        <path
+            android:name="background2"
+            android:fillColor="#FF000000"
+            android:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z" />
+    </group>
+    <group
+        android:translateX="50"
+        android:translateY="50" >
+        <path
+            android:name="twoLines"
+            android:pathData="M 100,20 l 0 80 l -30 -80"
+            android:strokeColor="#FF00FF00"
+            android:strokeLineCap="round"
+            android:strokeLineJoin="round"
+            android:strokeMiterLimit="10"
+            android:strokeWidth="20" />
+    </group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable28.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable28.xml
new file mode 100644
index 0000000..cd7bb16
--- /dev/null
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable28.xml
@@ -0,0 +1,45 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="64dp"
+    android:viewportHeight="200"
+    android:viewportWidth="200"
+    android:width="64dp" >
+
+    <group>
+        <path
+            android:name="background1"
+            android:fillColor="#FF000000"
+            android:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z" />
+        <path
+            android:name="background2"
+            android:fillColor="#FF000000"
+            android:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z" />
+    </group>
+    <group
+        android:translateX="50"
+        android:translateY="50" >
+        <path
+            android:name="twoLines"
+            android:pathData="M 100,20 l 0 80 l -30 -80"
+            android:strokeColor="#FF00FF00"
+            android:strokeLineCap="square"
+            android:strokeLineJoin="bevel"
+            android:strokeMiterLimit="10"
+            android:strokeWidth="20" />
+    </group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable_linear_progress_bar.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable_linear_progress_bar.xml
new file mode 100644
index 0000000..96fd70e
--- /dev/null
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable_linear_progress_bar.xml
@@ -0,0 +1,46 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="4dp"
+    android:viewportHeight="4"
+    android:viewportWidth="360"
+    android:width="360dp" >
+
+    <group
+        android:name="linear_indeterminate"
+        android:translateX="180.0"
+        android:translateY="0.0" >
+        <group
+            android:name="path1"
+            android:scaleX="0.1"
+            android:translateX="-522.59" >
+            <path
+                android:name="rect1"
+                android:fillColor="#FF000000"
+                android:pathData="l 288 0 l 0 4 l -288 0 z" />
+        </group>
+        <group
+            android:name="path2"
+            android:scaleX="0.1"
+            android:translateX="-197.6" >
+            <path
+                android:name="rect2"
+                android:fillColor="#FF000000"
+                android:pathData="l 288 0 l 0 4 l -288 0 z" />
+        </group>
+    </group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java
index b1ba0dd..f165cde 100644
--- a/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java
+++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java
@@ -22,10 +22,11 @@
 import android.widget.GridLayout;
 import android.widget.ScrollView;
 
-public class AnimatedVectorDrawableTest extends Activity implements View.OnClickListener{
+public class AnimatedVectorDrawableTest extends Activity implements View.OnClickListener {
     private static final String LOGCAT = "AnimatedVectorDrawableTest";
 
     protected int[] icon = {
+            R.drawable.animation_vector_linear_progress_bar,
             R.drawable.animation_vector_drawable_grouping_1,
             R.drawable.animation_vector_progress_bar,
             R.drawable.animation_vector_drawable_favorite,
diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
index e8b6952..37e0435 100644
--- a/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
+++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
@@ -53,6 +53,9 @@
             R.drawable.vector_drawable23,
             R.drawable.vector_drawable24,
             R.drawable.vector_drawable25,
+            R.drawable.vector_drawable26,
+            R.drawable.vector_drawable27,
+            R.drawable.vector_drawable28,
     };
 
     @Override
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
index b43ad6f..02610f8 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
@@ -20,6 +20,7 @@
 import android.os.Bundle;
 import android.service.voice.AlwaysOnHotwordDetector;
 import android.service.voice.AlwaysOnHotwordDetector.Callback;
+import android.service.voice.AlwaysOnHotwordDetector.TriggerAudio;
 import android.service.voice.VoiceInteractionService;
 import android.util.Log;
 
@@ -36,21 +37,11 @@
         }
 
         @Override
-        public void onDetected(byte[] data) {
+        public void onDetected(TriggerAudio triggerAudio) {
             Log.i(TAG, "onDetected");
         }
 
         @Override
-        public void onDetectionStarted() {
-            Log.i(TAG, "onDetectionStarted");
-        }
-
-        @Override
-        public void onDetectionStopped() {
-            Log.i(TAG, "onDetectionStopped");
-        }
-
-        @Override
         public void onError() {
             Log.i(TAG, "onError");
         }
@@ -95,8 +86,12 @@
                 break;
             case AlwaysOnHotwordDetector.STATE_KEYPHRASE_ENROLLED:
                 Log.i(TAG, "STATE_KEYPHRASE_ENROLLED - starting recognition");
-                mHotwordDetector.startRecognition(
-                        AlwaysOnHotwordDetector.RECOGNITION_FLAG_NONE);
+                if (mHotwordDetector.startRecognition(
+                        AlwaysOnHotwordDetector.RECOGNITION_FLAG_NONE)) {
+                    Log.i(TAG, "startRecognition succeeded");
+                } else {
+                    Log.i(TAG, "startRecognition failed");
+                }
                 break;
         }
     }
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 755a77a..ccbdadd 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -752,6 +752,7 @@
     config.screenWidthDp = 320;
     config.screenHeightDp = 480;
     config.smallestScreenWidthDp = 320;
+    config.screenLayout |= ResTable_config::SCREENSIZE_NORMAL;
     assets.setConfiguration(config);
 
     const ResTable& res = assets.getResources(false);
diff --git a/tools/layoutlib/.gitignore b/tools/layoutlib/.gitignore
index c5e82d7..eb52b64 100644
--- a/tools/layoutlib/.gitignore
+++ b/tools/layoutlib/.gitignore
@@ -1 +1,3 @@
-bin
\ No newline at end of file
+bin
+/.idea/workspace.xml
+/out
diff --git a/tools/layoutlib/.idea/.name b/tools/layoutlib/.idea/.name
new file mode 100644
index 0000000..10eb5c1
--- /dev/null
+++ b/tools/layoutlib/.idea/.name
@@ -0,0 +1 @@
+layoutlib
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/codeStyleSettings.xml b/tools/layoutlib/.idea/codeStyleSettings.xml
new file mode 100644
index 0000000..33937b3
--- /dev/null
+++ b/tools/layoutlib/.idea/codeStyleSettings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectCodeStyleSettingsManager">
+    <option name="PER_PROJECT_SETTINGS">
+      <value>
+        <option name="FIELD_NAME_PREFIX" value="m" />
+        <option name="STATIC_FIELD_NAME_PREFIX" value="s" />
+        <option name="USE_FQ_CLASS_NAMES_IN_JAVADOC" value="false" />
+        <option name="INSERT_INNER_CLASS_IMPORTS" value="true" />
+        <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
+        <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
+        <option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
+          <value />
+        </option>
+        <option name="IMPORT_LAYOUT_TABLE">
+          <value>
+            <package name="com.android" withSubpackages="true" static="false" />
+            <emptyLine />
+            <package name="org" withSubpackages="true" static="false" />
+            <emptyLine />
+            <package name="android" withSubpackages="true" static="false" />
+            <emptyLine />
+            <package name="java" withSubpackages="true" static="false" />
+            <emptyLine />
+            <package name="" withSubpackages="true" static="false" />
+            <emptyLine />
+            <package name="" withSubpackages="true" static="true" />
+          </value>
+        </option>
+        <option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
+        <option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
+        <option name="JD_ADD_BLANK_AFTER_PARM_COMMENTS" value="true" />
+        <option name="JD_ADD_BLANK_AFTER_RETURN" value="true" />
+        <option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true" />
+        <option name="RIGHT_MARGIN" value="100" />
+        <option name="WRAP_COMMENTS" value="true" />
+        <XML>
+          <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
+        </XML>
+        <codeStyleSettings language="JAVA">
+          <option name="INDENT_CASE_FROM_SWITCH" value="false" />
+          <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
+          <option name="CALL_PARAMETERS_WRAP" value="1" />
+          <option name="METHOD_PARAMETERS_WRAP" value="1" />
+          <option name="THROWS_LIST_WRAP" value="1" />
+          <option name="EXTENDS_KEYWORD_WRAP" value="1" />
+          <option name="THROWS_KEYWORD_WRAP" value="1" />
+          <option name="BINARY_OPERATION_WRAP" value="1" />
+          <option name="TERNARY_OPERATION_WRAP" value="1" />
+          <option name="ARRAY_INITIALIZER_WRAP" value="1" />
+          <option name="ASSIGNMENT_WRAP" value="1" />
+          <option name="ASSERT_STATEMENT_WRAP" value="1" />
+          <option name="IF_BRACE_FORCE" value="3" />
+          <option name="DOWHILE_BRACE_FORCE" value="3" />
+          <option name="WHILE_BRACE_FORCE" value="3" />
+          <option name="FOR_BRACE_FORCE" value="3" />
+          <arrangement>
+            <groups>
+              <group>
+                <type>GETTERS_AND_SETTERS</type>
+                <order>KEEP</order>
+              </group>
+              <group>
+                <type>OVERRIDDEN_METHODS</type>
+                <order>KEEP</order>
+              </group>
+            </groups>
+          </arrangement>
+        </codeStyleSettings>
+      </value>
+    </option>
+    <option name="USE_PER_PROJECT_SETTINGS" value="true" />
+  </component>
+</project>
+
diff --git a/tools/layoutlib/.idea/compiler.xml b/tools/layoutlib/.idea/compiler.xml
new file mode 100644
index 0000000..5aaaf18
--- /dev/null
+++ b/tools/layoutlib/.idea/compiler.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <option name="DEFAULT_COMPILER" value="Javac" />
+    <excludeFromCompile>
+      <directory url="file://$PROJECT_DIR$/create/tests/mock_data" includeSubdirectories="true" />
+    </excludeFromCompile>
+    <resourceExtensions />
+    <wildcardResourcePatterns>
+      <entry name="!?*.java" />
+      <entry name="!?*.form" />
+      <entry name="!?*.class" />
+      <entry name="!?*.groovy" />
+      <entry name="!?*.scala" />
+      <entry name="!?*.flex" />
+      <entry name="!?*.kt" />
+      <entry name="!?*.clj" />
+    </wildcardResourcePatterns>
+    <annotationProcessing>
+      <profile default="true" name="Default" enabled="false">
+        <processorPath useClasspath="true" />
+      </profile>
+    </annotationProcessing>
+    <bytecodeTargetLevel target="1.6" />
+  </component>
+</project>
+
diff --git a/tools/layoutlib/.idea/copyright/Android.xml b/tools/layoutlib/.idea/copyright/Android.xml
new file mode 100644
index 0000000..d81d75d
--- /dev/null
+++ b/tools/layoutlib/.idea/copyright/Android.xml
@@ -0,0 +1,9 @@
+<component name="CopyrightManager">
+  <copyright>
+    <option name="notice" value="Copyright (C) &amp;#36;today.year The Android Open Source Project&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10;     http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
+    <option name="keyword" value="Copyright" />
+    <option name="allowReplaceKeyword" value="" />
+    <option name="myName" value="Android" />
+    <option name="myLocal" value="true" />
+  </copyright>
+</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/copyright/profiles_settings.xml b/tools/layoutlib/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/tools/layoutlib/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+<component name="CopyrightManager">
+  <settings default="" />
+</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/encodings.xml b/tools/layoutlib/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/tools/layoutlib/.idea/encodings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
+</project>
+
diff --git a/tools/layoutlib/.idea/inspectionProfiles/Project_Default.xml b/tools/layoutlib/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..0ac7a44
--- /dev/null
+++ b/tools/layoutlib/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,11 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0" is_locked="false">
+    <option name="myName" value="Project Default" />
+    <option name="myLocal" value="false" />
+    <inspection_tool class="DefaultFileTemplate" enabled="false" level="WARNING" enabled_by_default="false">
+      <option name="CHECK_FILE_HEADER" value="true" />
+      <option name="CHECK_TRY_CATCH_SECTION" value="true" />
+      <option name="CHECK_METHOD_BODY" value="true" />
+    </inspection_tool>
+  </profile>
+</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/inspectionProfiles/profiles_settings.xml b/tools/layoutlib/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..3b31283
--- /dev/null
+++ b/tools/layoutlib/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,7 @@
+<component name="InspectionProjectProfileManager">
+  <settings>
+    <option name="PROJECT_PROFILE" value="Project Default" />
+    <option name="USE_PROJECT_PROFILE" value="true" />
+    <version value="1.0" />
+  </settings>
+</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/asm_4_0.xml b/tools/layoutlib/.idea/libraries/asm_4_0.xml
new file mode 100644
index 0000000..578a7bf
--- /dev/null
+++ b/tools/layoutlib/.idea/libraries/asm_4_0.xml
@@ -0,0 +1,11 @@
+<component name="libraryTable">
+  <library name="asm-4.0">
+    <CLASSES>
+      <root url="jar://$ANDROID_BUILD_TOP$/prebuilts/misc/common/asm/asm-4.0.jar!/" />
+    </CLASSES>
+    <JAVADOC />
+    <SOURCES>
+      <root url="jar://$ANDROID_BUILD_TOP$/prebuilts/misc/common/asm/src.zip!/" />
+    </SOURCES>
+  </library>
+</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/framework_jar.xml b/tools/layoutlib/.idea/libraries/framework_jar.xml
new file mode 100644
index 0000000..11f5b89
--- /dev/null
+++ b/tools/layoutlib/.idea/libraries/framework_jar.xml
@@ -0,0 +1,13 @@
+<component name="libraryTable">
+  <library name="framework.jar">
+    <CLASSES>
+      <root url="jar://$ANDROID_BUILD_TOP$/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar!/" />
+    </CLASSES>
+    <JAVADOC />
+    <SOURCES>
+      <root url="file://$ANDROID_BUILD_TOP$/frameworks/base/core/java" />
+      <root url="file://$ANDROID_BUILD_TOP$/frameworks/base/graphics/java" />
+      <root url="file://$ANDROID_BUILD_TOP$/libcore/luni/src/main/java" />
+    </SOURCES>
+  </library>
+</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/guava.xml b/tools/layoutlib/.idea/libraries/guava.xml
new file mode 100644
index 0000000..de5607e
--- /dev/null
+++ b/tools/layoutlib/.idea/libraries/guava.xml
@@ -0,0 +1,11 @@
+<component name="libraryTable">
+  <library name="guava">
+    <CLASSES>
+      <root url="jar://$ANDROID_BUILD_TOP$/out/host/common/obj/JAVA_LIBRARIES/guavalib_intermediates/javalib.jar!/" />
+    </CLASSES>
+    <JAVADOC />
+    <SOURCES>
+      <root url="file://$ANDROID_BUILD_TOP$/external/guava/guava/src" />
+    </SOURCES>
+  </library>
+</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/icu4j.xml b/tools/layoutlib/.idea/libraries/icu4j.xml
new file mode 100644
index 0000000..8d9a318
--- /dev/null
+++ b/tools/layoutlib/.idea/libraries/icu4j.xml
@@ -0,0 +1,11 @@
+<component name="libraryTable">
+  <library name="icu4j">
+    <CLASSES>
+      <root url="jar://$ANDROID_BUILD_TOP$/prebuilts/misc/common/icu4j/icu4j.jar!/" />
+    </CLASSES>
+    <JAVADOC>
+      <root url="http://icu-project.org/apiref/icu4j50rc/" />
+    </JAVADOC>
+    <SOURCES />
+  </library>
+</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/kxml2_2_3_0.xml b/tools/layoutlib/.idea/libraries/kxml2_2_3_0.xml
new file mode 100644
index 0000000..91feaea
--- /dev/null
+++ b/tools/layoutlib/.idea/libraries/kxml2_2_3_0.xml
@@ -0,0 +1,11 @@
+<component name="libraryTable">
+  <library name="kxml2-2.3.0">
+    <CLASSES>
+      <root url="jar://$ANDROID_BUILD_TOP$/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar!/" />
+    </CLASSES>
+    <JAVADOC />
+    <SOURCES>
+      <root url="file://$ANDROID_BUILD_TOP$/libcore/xml/src/main/java" />
+    </SOURCES>
+  </library>
+</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml b/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml
new file mode 100644
index 0000000..be928da
--- /dev/null
+++ b/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml
@@ -0,0 +1,11 @@
+<component name="libraryTable">
+  <library name="layoutlib_api-prebuilt">
+    <CLASSES>
+      <root url="jar://$ANDROID_BUILD_TOP$/prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar!/" />
+    </CLASSES>
+    <JAVADOC />
+    <SOURCES>
+      <root url="file://$ANDROID_SRC$/tools/base/layoutlib-api/src/main/java" />
+    </SOURCES>
+  </library>
+</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/ninepatch_prebuilt.xml b/tools/layoutlib/.idea/libraries/ninepatch_prebuilt.xml
new file mode 100644
index 0000000..338137b
--- /dev/null
+++ b/tools/layoutlib/.idea/libraries/ninepatch_prebuilt.xml
@@ -0,0 +1,11 @@
+<component name="libraryTable">
+  <library name="ninepatch-prebuilt">
+    <CLASSES>
+      <root url="jar://$ANDROID_BUILD_TOP$/prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar!/" />
+    </CLASSES>
+    <JAVADOC />
+    <SOURCES>
+      <root url="file://$ANDROID_SRC$/tools/base/ninepatch/src/main/java" />
+    </SOURCES>
+  </library>
+</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/tools_common_prebuilt.xml b/tools/layoutlib/.idea/libraries/tools_common_prebuilt.xml
new file mode 100644
index 0000000..6479886
--- /dev/null
+++ b/tools/layoutlib/.idea/libraries/tools_common_prebuilt.xml
@@ -0,0 +1,14 @@
+<component name="libraryTable">
+  <library name="tools-common-prebuilt">
+    <ANNOTATIONS>
+      <root url="file://$PROJECT_DIR$" />
+    </ANNOTATIONS>
+    <CLASSES>
+      <root url="jar://$ANDROID_BUILD_TOP$/prebuilts/misc/common/tools-common/tools-common-prebuilt.jar!/" />
+    </CLASSES>
+    <JAVADOC />
+    <SOURCES>
+      <root url="file://$ANDROID_SRC$/tools/base/common/src/main/java" />
+    </SOURCES>
+  </library>
+</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/misc.xml b/tools/layoutlib/.idea/misc.xml
new file mode 100644
index 0000000..fd63e6c
--- /dev/null
+++ b/tools/layoutlib/.idea/misc.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="EntryPointsManager">
+    <entry_points version="2.0" />
+    <list size="1">
+      <item index="0" class="java.lang.String" itemvalue="com.android.tools.layoutlib.annotations.LayoutlibDelegate" />
+    </list>
+  </component>
+  <component name="FrameworkDetectionExcludesConfiguration">
+    <type id="android" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>
+
diff --git a/tools/layoutlib/.idea/modules.xml b/tools/layoutlib/.idea/modules.xml
new file mode 100644
index 0000000..684f4fd
--- /dev/null
+++ b/tools/layoutlib/.idea/modules.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/bridge/bridge.iml" filepath="$PROJECT_DIR$/bridge/bridge.iml" />
+      <module fileurl="file://$PROJECT_DIR$/create/create.iml" filepath="$PROJECT_DIR$/create/create.iml" />
+    </modules>
+  </component>
+</project>
+
diff --git a/tools/layoutlib/.idea/runConfigurations/All_in_bridge.xml b/tools/layoutlib/.idea/runConfigurations/All_in_bridge.xml
new file mode 100644
index 0000000..badbbab
--- /dev/null
+++ b/tools/layoutlib/.idea/runConfigurations/All_in_bridge.xml
@@ -0,0 +1,31 @@
+<component name="ProjectRunConfigurationManager">
+  <configuration default="false" name="All in bridge" type="JUnit" factoryName="JUnit" singleton="true" nameIsGenerated="true">
+    <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+    <module name="bridge" />
+    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+    <option name="ALTERNATIVE_JRE_PATH" value="" />
+    <option name="PACKAGE_NAME" value="" />
+    <option name="MAIN_CLASS_NAME" value="" />
+    <option name="METHOD_NAME" value="" />
+    <option name="TEST_OBJECT" value="package" />
+    <option name="VM_PARAMETERS" value="-ea -Dplatform.dir=&quot;$ANDROID_BUILD_TOP$/out/host/linux-x86/sdk/sdk/android-sdk_eng.deepanshu_linux-x86/platforms/android-L&quot; -Dtest_res.dir=&quot;$PROJECT_DIR$/bridge/tests/res&quot;" />
+    <option name="PARAMETERS" value="" />
+    <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
+    <option name="ENV_VARIABLES" />
+    <option name="PASS_PARENT_ENVS" value="true" />
+    <option name="TEST_SEARCH_SCOPE">
+      <value defaultName="singleModule" />
+    </option>
+    <envs />
+    <patterns />
+    <RunnerSettings RunnerId="Debug">
+      <option name="DEBUG_PORT" value="" />
+      <option name="TRANSPORT" value="0" />
+      <option name="LOCAL" value="true" />
+    </RunnerSettings>
+    <RunnerSettings RunnerId="Run" />
+    <ConfigurationWrapper RunnerId="Debug" />
+    <ConfigurationWrapper RunnerId="Run" />
+    <method />
+  </configuration>
+</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/runConfigurations/All_in_create.xml b/tools/layoutlib/.idea/runConfigurations/All_in_create.xml
new file mode 100644
index 0000000..b9cd419
--- /dev/null
+++ b/tools/layoutlib/.idea/runConfigurations/All_in_create.xml
@@ -0,0 +1,31 @@
+<component name="ProjectRunConfigurationManager">
+  <configuration default="false" name="All in create" type="JUnit" factoryName="JUnit" singleton="false" nameIsGenerated="true">
+    <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+    <module name="create" />
+    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+    <option name="ALTERNATIVE_JRE_PATH" value="" />
+    <option name="PACKAGE_NAME" value="" />
+    <option name="MAIN_CLASS_NAME" value="" />
+    <option name="METHOD_NAME" value="" />
+    <option name="TEST_OBJECT" value="package" />
+    <option name="VM_PARAMETERS" value="-ea" />
+    <option name="PARAMETERS" value="" />
+    <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
+    <option name="ENV_VARIABLES" />
+    <option name="PASS_PARENT_ENVS" value="true" />
+    <option name="TEST_SEARCH_SCOPE">
+      <value defaultName="singleModule" />
+    </option>
+    <envs />
+    <patterns />
+    <RunnerSettings RunnerId="Debug">
+      <option name="DEBUG_PORT" value="" />
+      <option name="TRANSPORT" value="0" />
+      <option name="LOCAL" value="true" />
+    </RunnerSettings>
+    <RunnerSettings RunnerId="Run" />
+    <ConfigurationWrapper RunnerId="Debug" />
+    <ConfigurationWrapper RunnerId="Run" />
+    <method />
+  </configuration>
+</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/runConfigurations/Create.xml b/tools/layoutlib/.idea/runConfigurations/Create.xml
new file mode 100644
index 0000000..e62925b
--- /dev/null
+++ b/tools/layoutlib/.idea/runConfigurations/Create.xml
@@ -0,0 +1,25 @@
+<component name="ProjectRunConfigurationManager">
+  <configuration default="false" name="Create" type="Application" factoryName="Application" singleton="true">
+    <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+    <option name="MAIN_CLASS_NAME" value="com.android.tools.layoutlib.create.Main" />
+    <option name="VM_PARAMETERS" value="" />
+    <option name="PROGRAM_PARAMETERS" value="out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar out/target/common/obj/JAVA_LIBRARIES/core-libart_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/javalib.jar" />
+    <option name="WORKING_DIRECTORY" value="file://$ANDROID_BUILD_TOP$/" />
+    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
+    <option name="ALTERNATIVE_JRE_PATH" value="1.6" />
+    <option name="ENABLE_SWING_INSPECTOR" value="false" />
+    <option name="ENV_VARIABLES" />
+    <option name="PASS_PARENT_ENVS" value="true" />
+    <module name="create" />
+    <envs />
+    <RunnerSettings RunnerId="Debug">
+      <option name="DEBUG_PORT" value="" />
+      <option name="TRANSPORT" value="0" />
+      <option name="LOCAL" value="true" />
+    </RunnerSettings>
+    <RunnerSettings RunnerId="Run" />
+    <ConfigurationWrapper RunnerId="Debug" />
+    <ConfigurationWrapper RunnerId="Run" />
+    <method />
+  </configuration>
+</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/scopes/scope_settings.xml b/tools/layoutlib/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/tools/layoutlib/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+<component name="DependencyValidationManager">
+  <state>
+    <option name="SKIP_IMPORT_STATEMENTS" value="false" />
+  </state>
+</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/uiDesigner.xml b/tools/layoutlib/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/tools/layoutlib/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Palette2">
+    <group name="Swing">
+      <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
+      </item>
+      <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
+        <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
+        <initial-values>
+          <property name="text" value="Button" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="RadioButton" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="CheckBox" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="Label" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
+          <preferred-size width="-1" height="20" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
+      </item>
+    </group>
+  </component>
+</project>
+
diff --git a/tools/layoutlib/.idea/vcs.xml b/tools/layoutlib/.idea/vcs.xml
new file mode 100644
index 0000000..8114960
--- /dev/null
+++ b/tools/layoutlib/.idea/vcs.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$ANDROID_BUILD_TOP$/frameworks/base" vcs="Git" />
+  </component>
+</project>
+
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
index aef3efa..9c4160c 100644
--- a/tools/layoutlib/bridge/.classpath
+++ b/tools/layoutlib/bridge/.classpath
@@ -10,5 +10,7 @@
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/tools-common/tools-common-prebuilt.jar"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/icu4j/icu4j.jar"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/sdk-common/sdk-common.jar"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/guavalib_intermediates/javalib.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/tools/layoutlib/bridge/bridge.iml b/tools/layoutlib/bridge/bridge.iml
new file mode 100644
index 0000000..7553b59
--- /dev/null
+++ b/tools/layoutlib/bridge/bridge.iml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/tests/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/tests/src" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/.settings" />
+      <excludeFolder url="file://$MODULE_DIR$/bin" />
+      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/.gradle" />
+      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/.idea" />
+      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/generated" />
+      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/assets" />
+      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/dependency-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/incremental" />
+      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/libs" />
+      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/manifests" />
+      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/res" />
+      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/rs" />
+      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/symbols" />
+      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/gradle" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="icu4j" level="project" />
+    <orderEntry type="library" name="kxml2-2.3.0" level="project" />
+    <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
+    <orderEntry type="library" name="ninepatch-prebuilt" level="project" />
+    <orderEntry type="library" name="tools-common-prebuilt" level="project" />
+    <orderEntry type="library" name="framework.jar" level="project" />
+    <orderEntry type="library" scope="TEST" name="guava" level="project" />
+    <orderEntry type="module-library" scope="TEST">
+      <library>
+        <CLASSES>
+          <root url="jar://$ANDROID_BUILD_TOP$/prebuilts/misc/common/sdk-common/sdk-common.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$ANDROID_BUILD_TOP$/prebuilts/misc/common/sdk-common/sdk-common-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="library" scope="TEST" name="JUnit4" level="application" />
+  </component>
+</module>
+
diff --git a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java b/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
index 88ebd1f..154851b 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
@@ -16,6 +16,9 @@
 
 package android.graphics;
 
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+
 import java.awt.Font;
 import java.awt.Graphics2D;
 import java.awt.Toolkit;
@@ -58,6 +61,8 @@
     private final Graphics2D mGraphics;
     private final Paint_Delegate mPaint;
     private char[] mText;
+    // This List can contain nulls. A null font implies that the we weren't able to load the font
+    // properly. So, if we encounter a situation where we try to use that font, log a warning.
     private List<Font> mFonts;
     // Bounds of the text drawn so far.
     private RectF mBounds;
@@ -169,6 +174,10 @@
             // fonts to check which one can draw it.
             int charCount = Character.isHighSurrogate(mText[start]) ? 2 : 1;
             for (Font font : mFonts) {
+                if (font == null) {
+                    logFontWarning();
+                    continue;
+                }
                 canDisplayUpTo = font.canDisplayUpTo(mText, start, start + charCount);
                 if (canDisplayUpTo == -1) {
                     render(start, start+charCount, font, flag, advances, advancesIndex, draw);
@@ -191,6 +200,12 @@
         }
     }
 
+    private static void logFontWarning() {
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
+                "Some fonts could not be loaded. The rendering may not be perfect. " +
+                        "Try running the IDE with JRE 7.", null, null);
+    }
+
     /**
      * Renders the text to the right of the bounds with the given font.
      * @param font The font to render the text with.
@@ -266,6 +281,10 @@
     private static void setScriptFont(char[] text, ScriptRun run,
             List<Font> fonts) {
         for (Font font : fonts) {
+            if (font == null) {
+                logFontWarning();
+                continue;
+            }
             if (font.canDisplayUpTo(text, run.start, run.limit) == -1) {
                 run.font = font;
                 return;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index 2ff0fc1..be75dde 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -132,20 +132,6 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static long initCanvas(long nativeCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate nativeCanvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (nativeCanvasDelegate == null) {
-            return 0;
-        }
-
-        Canvas_Delegate newDelegate = new Canvas_Delegate();
-
-        // TODO: actually copy the canvas state.
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
     /*package*/
     static void native_setBitmap(long canvas, long bitmap, boolean copyState) {
         Canvas_Delegate canvasDelegate = sManager.getDelegate(canvas);
@@ -498,24 +484,6 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static void native_drawRGB(long nativeCanvas, int r, int g, int b) {
-        native_drawColor(nativeCanvas, 0xFF000000 | r << 16 | (g&0xFF) << 8 | (b&0xFF),
-                PorterDuff.Mode.SRC_OVER.nativeInt);
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawARGB(long nativeCanvas, int a, int r, int g, int b) {
-        native_drawColor(nativeCanvas, a << 24 | (r&0xFF) << 16 | (g&0xFF) << 8 | (b&0xFF),
-                PorterDuff.Mode.SRC_OVER.nativeInt);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawColor(long nativeCanvas, int color) {
-        native_drawColor(nativeCanvas, color, PorterDuff.Mode.SRC_OVER.nativeInt);
-    }
-
-    @LayoutlibDelegate
     /*package*/ static void native_drawColor(long nativeCanvas, final int color, final int mode) {
         // get the delegate from the native int.
         Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
@@ -772,52 +740,18 @@
 
     @LayoutlibDelegate
     /*package*/ static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, long bitmap,
-                                                 Rect src, RectF dst,
-                                                 long nativePaintOrZero,
-                                                 int screenDensity,
-                                                 int bitmapDensity) {
+                                 float srcLeft, float srcTop, float srcRight, float srcBottom,
+                                 float dstLeft, float dstTop, float dstRight, float dstBottom,
+                                 long nativePaintOrZero, int screenDensity, int bitmapDensity) {
         // get the delegate from the native int.
         Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
         if (bitmapDelegate == null) {
             return;
         }
 
-        BufferedImage image = bitmapDelegate.getImage();
-
-        if (src == null) {
-            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
-                    0, 0, image.getWidth(), image.getHeight(),
-                    (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom);
-        } else {
-            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
-                    src.left, src.top, src.width(), src.height(),
-                    (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawBitmap(long nativeCanvas, long bitmap,
-                                                 Rect src, Rect dst,
-                                                 long nativePaintOrZero,
-                                                 int screenDensity,
-                                                 int bitmapDensity) {
-        // get the delegate from the native int.
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
-        if (bitmapDelegate == null) {
-            return;
-        }
-
-        BufferedImage image = bitmapDelegate.getImage();
-
-        if (src == null) {
-            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
-                    0, 0, image.getWidth(), image.getHeight(),
-                    dst.left, dst.top, dst.right, dst.bottom);
-        } else {
-            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
-                    src.left, src.top, src.width(), src.height(),
-                    dst.left, dst.top, dst.right, dst.bottom);
-        }
+        drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
+                (int)srcLeft, (int)srcTop, (int)srcRight, (int)srcBottom,
+                (int)dstLeft, (int)dstTop, (int)dstRight, (int)dstBottom);
     }
 
     @LayoutlibDelegate
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
index 30b0ce5..de3307f 100644
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
@@ -24,6 +24,7 @@
 import android.content.res.AssetManager;
 
 import java.awt.Font;
+import java.awt.FontFormatException;
 import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
@@ -152,14 +153,20 @@
             try {
                 return Font.createFont(Font.TRUETYPE_FONT, f);
             } catch (Exception e) {
+                if (path.endsWith(".otf") && e instanceof FontFormatException) {
+                    // If we aren't able to load an Open Type font, don't log a warning just yet.
+                    // We wait for a case where font is being used. Only then we try to log the
+                    // warning.
+                    return null;
+                }
                 Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
                         String.format("Unable to load font %1$s", relativePath),
-                        e /*throwable*/, null /*data*/);
+                        e, null);
             }
         } else {
             Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
                     "Only platform fonts located in " + SYSTEM_FONTS + "can be loaded.",
-                    null /*throwable*/, null /*data*/);
+                    null, null);
         }
 
         return null;
@@ -206,7 +213,7 @@
     @LayoutlibDelegate
     /*package*/ static boolean nAddFontFromAsset(long nativeFamily, AssetManager mgr, String path) {
         Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "FontFamily.addFontFromAsset is not supported.", null /*throwable*/, null /*data*/);
+                "FontFamily.addFontFromAsset is not supported.", null, null);
         return false;
     }
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
index 74b2893..e16dbda 100644
--- a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
@@ -215,9 +215,9 @@
         if (c == null) {
             // not a 9-patch?
             BufferedImage image = bitmap_delegate.getImage();
-            Canvas_Delegate.native_drawBitmap(canvas_instance, bitmap_instance,
-                    new Rect(0, 0, image.getWidth(), image.getHeight()),
-                    new Rect(left, top, right, bottom),
+            Canvas_Delegate.native_drawBitmap(null, canvas_instance, bitmap_instance,
+                    0f, 0f, (float)image.getWidth(), (float)image.getHeight(),
+                    (float)left, (float)top, (float)right, (float)bottom,
                     paint_instance_or_null, destDensity, srcDensity);
             return;
         }
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index 24ef189..73d67a7 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -1084,6 +1084,22 @@
         sManager.removeJavaReferenceFor(nativePaint);
     }
 
+    @LayoutlibDelegate
+    /*package*/ static float native_getLetterSpacing(long nativePaint) {
+        // TODO: throw a fidelity warning.
+        return 0;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setLetterSpacing(long nativePaint, float letterSpacing) {
+        // pass.
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setFontFeatureSettings(long nativePaint, String settings) {
+        // pass.
+    }
+
     // ---- Private delegate/helper methods ----
 
     /*package*/ Paint_Delegate() {
diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
index 14e9960..832d0a3 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
@@ -76,19 +76,22 @@
     // ---- native methods ----
 
     @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(long native_shader) {
+    /*package*/ static void nativeDestructor(long native_shader, long native_with_local_matrix) {
+        // TODO: check what's native_with_local_matrix
         sManager.removeJavaReferenceFor(native_shader);
     }
 
     @LayoutlibDelegate
-    /*package*/ static void nativeSetLocalMatrix(long native_shader, long matrix_instance) {
+    /*package*/ static long nativeSetLocalMatrix(long native_shader,
+            long native_with_local_matrix, long matrix_instance) {
         // get the delegate from the native int.
         Shader_Delegate shaderDelegate = sManager.getDelegate(native_shader);
         if (shaderDelegate == null) {
-            return;
+            return 0;
         }
 
         shaderDelegate.mLocalMatrix = Matrix_Delegate.getDelegate(matrix_instance);
+        return 0;
     }
 
     // ---- Private delegate/helper methods ----
diff --git a/tools/layoutlib/bridge/src/android/os/SystemProperties_Delegate.java b/tools/layoutlib/bridge/src/android/os/SystemProperties_Delegate.java
index 1e7564e..af0c456 100644
--- a/tools/layoutlib/bridge/src/android/os/SystemProperties_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/os/SystemProperties_Delegate.java
@@ -48,4 +48,58 @@
 
         return def;
     }
+    @LayoutlibDelegate
+    /*package*/ static int native_get_int(String key, int def) {
+        Map<String, String> properties = Bridge.getPlatformProperties();
+        String value = properties.get(key);
+        if (value != null) {
+            return Integer.decode(value);
+        }
+
+        return def;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static long native_get_long(String key, long def) {
+        Map<String, String> properties = Bridge.getPlatformProperties();
+        String value = properties.get(key);
+        if (value != null) {
+            return Long.decode(value);
+        }
+
+        return def;
+    }
+
+    /**
+     * Values 'n', 'no', '0', 'false' or 'off' are considered false.
+     * Values 'y', 'yes', '1', 'true' or 'on' are considered true.
+     */
+    @LayoutlibDelegate
+    /*package*/ static boolean native_get_boolean(String key, boolean def) {
+        Map<String, String> properties = Bridge.getPlatformProperties();
+        String value = properties.get(key);
+
+        if ("n".equals(value) || "no".equals(value) || "0".equals(value) || "false".equals(value)
+                || "off".equals(value)) {
+            return false;
+        }
+        //noinspection SimplifiableIfStatement
+        if ("y".equals(value) || "yes".equals(value) || "1".equals(value) || "true".equals(value)
+                || "on".equals(value)) {
+            return true;
+        }
+
+        return def;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_set(String key, String def) {
+        Map<String, String> properties = Bridge.getPlatformProperties();
+        properties.put(key, def);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_add_change_callback() {
+        // pass.
+    }
 }
diff --git a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
new file mode 100644
index 0000000..5a467b2
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
@@ -0,0 +1,55 @@
+package android.text;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.text.CharacterIterator;
+import java.util.Arrays;
+import java.util.Locale;
+
+import com.ibm.icu.lang.UCharacter;
+import com.ibm.icu.text.BreakIterator;
+import com.ibm.icu.util.ULocale;
+import javax.swing.text.Segment;
+
+/**
+ * Delegate that provides implementation for native methods in {@link android.text.StaticLayout}
+ *
+ * Through the layoutlib_create tool, selected methods of Handler have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ */
+public class StaticLayout_Delegate {
+
+    /**
+     * Fills the recycle array with positions that are suitable to break the text at. The array
+     * must be terminated by '-1'.
+     */
+    @LayoutlibDelegate
+    /*package*/ static int[] nLineBreakOpportunities(String locale, char[] text, int length,
+            int[] recycle) {
+        BreakIterator iterator = BreakIterator.getLineInstance(new ULocale(locale));
+        Segment segment = new Segment(text, 0, length);
+        iterator.setText(segment);
+        if (recycle == null) {
+            // Because 42 is the answer to everything.
+            recycle = new int[42];
+        }
+        int breakOpp = iterator.first();
+        recycle[0] = breakOpp;
+        //noinspection ConstantConditions
+        assert BreakIterator.DONE == -1;
+        for (int i = 1; breakOpp != BreakIterator.DONE; ++i) {
+            if (i >= recycle.length) {
+                recycle = doubleSize(recycle);
+            }
+            assert (i < recycle.length);
+            breakOpp = iterator.next();
+            recycle[i] = breakOpp;
+        }
+        return recycle;
+    }
+
+    private static int[] doubleSize(int[] array) {
+        return Arrays.copyOf(array, array.length * 2);
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/text/format/Time_Delegate.java b/tools/layoutlib/bridge/src/android/text/format/Time_Delegate.java
index 320dd0d..ed8498f 100644
--- a/tools/layoutlib/bridge/src/android/text/format/Time_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/text/format/Time_Delegate.java
@@ -39,91 +39,6 @@
     // Format used by toString()
     private static final String FORMAT = "%1$tY%1$tm%1$tdT%1$tH%1$tM%1$tS<%1$tZ>";
 
-    @LayoutlibDelegate
-    /*package*/ static long normalize(Time thisTime, boolean ignoreDst) {
-        long millis = toMillis(thisTime, ignoreDst);
-        set(thisTime, millis);
-        return millis;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void switchTimezone(Time thisTime, String timezone) {
-        Calendar c = timeToCalendar(thisTime);
-        c.setTimeZone(TimeZone.getTimeZone(timezone));
-        calendarToTime(c, thisTime);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCompare(Time a, Time b) {
-      return timeToCalendar(a).compareTo(timeToCalendar(b));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String format1(Time thisTime, String format) {
-
-        try {
-            // Change the format by adding changing '%' to "%1$t". This is required to tell the
-            // formatter which argument to use from the argument list. '%%' is left as is. In the
-            // replacement string, $0 refers to matched pattern. \\1 means '1', written this way to
-            // separate it from 0. \\$ means '$', written this way to suppress the special meaning
-            // of $.
-            return String.format(
-                    p.matcher(format).replaceAll("$0\\1\\$t"),
-                    timeToCalendar(thisTime));
-        } catch (UnknownFormatConversionException e) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_STRFTIME, "Unrecognized format", e, format);
-            return format;
-        }
-    }
-
-    /**
-     * Return the current time in YYYYMMDDTHHMMSS<tz> format
-     */
-    @LayoutlibDelegate
-    /*package*/ static String toString(Time thisTime) {
-        Calendar c = timeToCalendar(thisTime);
-        return String.format(FORMAT, c);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeParse(Time thisTime, String s) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "android.text.format.Time.parse() not supported.", null);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeParse3339(Time thisTime, String s) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "android.text.format.Time.parse3339() not supported.", null);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setToNow(Time thisTime) {
-        calendarToTime(getCalendarInstance(thisTime), thisTime);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long toMillis(Time thisTime, boolean ignoreDst) {
-        // TODO: Respect ignoreDst.
-        return timeToCalendar(thisTime).getTimeInMillis();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void set(Time thisTime, long millis) {
-        Calendar c = getCalendarInstance(thisTime);
-        c.setTimeInMillis(millis);
-        calendarToTime(c,thisTime);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String format2445(Time thisTime) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "android.text.format.Time.format2445() not supported.", null);
-        return "";
-    }
-
     // ---- private helper methods ----
 
     private static Calendar timeToCalendar(Time time) {
diff --git a/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java b/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java
index 1fd7836..d5170aa 100644
--- a/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java
+++ b/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java
@@ -16,6 +16,8 @@
 
 package android.view.accessibility;
 
+import com.android.annotations.NonNull;
+
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.content.Context;
 import android.content.pm.ServiceInfo;
@@ -31,14 +33,16 @@
  * for example an {@link android.app.Activity} starts, the focus or selection of a
  * {@link android.view.View} changes etc. Parties interested in handling accessibility
  * events implement and register an accessibility service which extends
- * {@link android.accessibilityservice.AccessibilityService}.
+ * {@code android.accessibilityservice.AccessibilityService}.
  *
  * @see AccessibilityEvent
- * @see android.accessibilityservice.AccessibilityService
  * @see android.content.Context#getSystemService
  */
+@SuppressWarnings("UnusedDeclaration")
 public final class AccessibilityManager {
-    private static AccessibilityManager sInstance = new AccessibilityManager();
+
+    private static AccessibilityManager sInstance = new AccessibilityManager(null, null, 0);
+
 
     /**
      * Listener for the accessibility state.
@@ -54,9 +58,46 @@
     }
 
     /**
+     * Listener for the system touch exploration state. To listen for changes to
+     * the touch exploration state on the device, implement this interface and
+     * register it with the system by calling
+     * {@link #addTouchExplorationStateChangeListener}.
+     */
+    public interface TouchExplorationStateChangeListener {
+
+        /**
+         * Called when the touch exploration enabled state changes.
+         *
+         * @param enabled Whether touch exploration is enabled.
+         */
+        public void onTouchExplorationStateChanged(boolean enabled);
+    }
+
+    /**
+     * Listener for the system high text contrast state. To listen for changes to
+     * the high text contrast state on the device, implement this interface and
+     * register it with the system by calling
+     * {@link #addHighTextContrastStateChangeListener}.
+     */
+    public interface HighTextContrastChangeListener {
+
+        /**
+         * Called when the high text contrast enabled state changes.
+         *
+         * @param enabled Whether high text contrast is enabled.
+         */
+        public void onHighTextContrastStateChanged(boolean enabled);
+    }
+
+    private final IAccessibilityManagerClient.Stub mClient =
+            new IAccessibilityManagerClient.Stub() {
+                public void setState(int state) {
+                }
+            };
+
+    /**
      * Get an AccessibilityManager instance (create one if necessary).
      *
-     * @hide
      */
     public static AccessibilityManager getInstance(Context context) {
         return sInstance;
@@ -67,7 +108,11 @@
      *
      * @param context A {@link Context}.
      */
-    private AccessibilityManager() {
+    public AccessibilityManager(Context context, IAccessibilityManager service, int userId) {
+    }
+
+    public IAccessibilityManagerClient getClient() {
+        return mClient;
     }
 
     /**
@@ -80,13 +125,28 @@
     }
 
     /**
-     * Sends an {@link AccessibilityEvent}. If this {@link AccessibilityManager} is not
-     * enabled the call is a NOOP.
+     * Returns if the touch exploration in the system is enabled.
      *
-     * @param event The {@link AccessibilityEvent}.
+     * @return True if touch exploration is enabled, false otherwise.
+     */
+    public boolean isTouchExplorationEnabled() {
+        return true;
+    }
+
+    /**
+     * Returns if the high text contrast in the system is enabled.
+     * <p>
+     * <strong>Note:</strong> You need to query this only if you application is
+     * doing its own rendering and does not rely on the platform rendering pipeline.
+     * </p>
      *
-     * @throws IllegalStateException if a client tries to send an {@link AccessibilityEvent}
-     *         while accessibility is not enabled.
+     */
+    public boolean isHighTextContrastEnabled() {
+        return false;
+    }
+
+    /**
+     * Sends an {@link AccessibilityEvent}.
      */
     public void sendAccessibilityEvent(AccessibilityEvent event) {
     }
@@ -102,20 +162,40 @@
      *
      * @return An unmodifiable list with {@link ServiceInfo}s.
      */
+    @Deprecated
     public List<ServiceInfo> getAccessibilityServiceList() {
-        // normal implementation does this in some case, so let's do the same
-        // (unmodifiableList wrapped around null).
-        List<ServiceInfo> services = null;
-        return Collections.unmodifiableList(services);
+        return Collections.emptyList();
     }
 
     public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList() {
-        // normal implementation does this in some case, so let's do the same
-        // (unmodifiableList wrapped around null).
-        List<AccessibilityServiceInfo> services = null;
-        return Collections.unmodifiableList(services);
+        return Collections.emptyList();
     }
 
+    /**
+     * Returns the {@link AccessibilityServiceInfo}s of the enabled accessibility services
+     * for a given feedback type.
+     *
+     * @param feedbackTypeFlags The feedback type flags.
+     * @return An unmodifiable list with {@link AccessibilityServiceInfo}s.
+     *
+     * @see AccessibilityServiceInfo#FEEDBACK_AUDIBLE
+     * @see AccessibilityServiceInfo#FEEDBACK_GENERIC
+     * @see AccessibilityServiceInfo#FEEDBACK_HAPTIC
+     * @see AccessibilityServiceInfo#FEEDBACK_SPOKEN
+     * @see AccessibilityServiceInfo#FEEDBACK_VISUAL
+     */
+    public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(
+            int feedbackTypeFlags) {
+        return Collections.emptyList();
+    }
+
+    /**
+     * Registers an {@link AccessibilityStateChangeListener} for changes in
+     * the global accessibility state of the system.
+     *
+     * @param listener The listener.
+     * @return True if successfully registered.
+     */
     public boolean addAccessibilityStateChangeListener(
             AccessibilityStateChangeListener listener) {
         return true;
@@ -126,6 +206,62 @@
         return true;
     }
 
+    /**
+     * Registers a {@link TouchExplorationStateChangeListener} for changes in
+     * the global touch exploration state of the system.
+     *
+     * @param listener The listener.
+     * @return True if successfully registered.
+     */
+    public boolean addTouchExplorationStateChangeListener(
+            @NonNull TouchExplorationStateChangeListener listener) {
+        return true;
+    }
+
+    /**
+     * Unregisters a {@link TouchExplorationStateChangeListener}.
+     *
+     * @param listener The listener.
+     * @return True if successfully unregistered.
+     */
+    public boolean removeTouchExplorationStateChangeListener(
+            @NonNull TouchExplorationStateChangeListener listener) {
+        return true;
+    }
+
+    /**
+     * Registers a {@link HighTextContrastChangeListener} for changes in
+     * the global high text contrast state of the system.
+     *
+     * @param listener The listener.
+     * @return True if successfully registered.
+     *
+     */
+    public boolean addHighTextContrastStateChangeListener(
+            @NonNull HighTextContrastChangeListener listener) {
+        return true;
+    }
+
+    /**
+     * Unregisters a {@link HighTextContrastChangeListener}.
+     *
+     * @param listener The listener.
+     * @return True if successfully unregistered.
+     *
+     */
+    public boolean removeHighTextContrastStateChangeListener(
+            @NonNull HighTextContrastChangeListener listener) {
+        return true;
+    }
+
+    /**
+     * Sets the current state and notifies listeners, if necessary.
+     *
+     * @param stateFlags The state flags.
+     */
+    private void setStateLocked(int stateFlags) {
+    }
+
     public int addAccessibilityInteractionConnection(IWindow windowToken,
             IAccessibilityInteractionConnection connection) {
         return View.NO_ID;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index cc69af2..3d0e1e8 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -290,7 +290,7 @@
             if (log != null) {
                 log.error(LayoutLog.TAG_BROKEN,
                         "Failed to load com.android.internal.R from the layout library jar",
-                        throwable);
+                        throwable, null);
             }
             return false;
         }
@@ -418,8 +418,7 @@
             locale = "";
         }
         ULocale uLocale = new ULocale(locale);
-        return uLocale.getCharacterOrientation().equals(ICU_LOCALE_DIRECTION_RTL) ?
-                true : false;
+        return uLocale.getCharacterOrientation().equals(ICU_LOCALE_DIRECTION_RTL);
     }
 
     /**
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java
index 607e628..ea5f1ea 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java
@@ -33,4 +33,27 @@
     public static String toLanguageTag(Locale locale)  {
         return ULocale.forLocale(locale).toLanguageTag();
     }
+
+    public static String adjustLanguageCode(String languageCode) {
+        String adjusted = languageCode.toLowerCase(Locale.US);
+        // Map new language codes to the obsolete language
+        // codes so the correct resource bundles will be used.
+        if (languageCode.equals("he")) {
+            adjusted = "iw";
+        } else if (languageCode.equals("id")) {
+            adjusted = "in";
+        } else if (languageCode.equals("yi")) {
+            adjusted = "ji";
+        }
+
+        return adjusted;
+    }
+
+    public static Locale forLanguageTag(String tag) {
+        return ULocale.forLanguageTag(tag).toLocale();
+    }
+
+    public static String getScript(Locale locale) {
+        return ULocale.forLocale(locale).getScript();
+    }
 }
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 03b5211..04a52ea 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
@@ -967,6 +967,12 @@
     }
 
     @Override
+    public Context createApplicationContext(ApplicationInfo application, int flags)
+            throws PackageManager.NameNotFoundException {
+        return null;
+    }
+
+    @Override
     public boolean deleteDatabase(String arg0) {
         // pass
         return false;
diff --git a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
index 71947b0..8898856 100644
--- a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
+++ b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
@@ -177,12 +177,6 @@
         return Locale.getISOCountries();
     }
 
-
-    @LayoutlibDelegate
-    /*package*/ static String localeForLanguageTag(String languageTag, boolean strict) {
-        return "";
-    }
-
     @LayoutlibDelegate
     /*package*/ static boolean initLocaleDataNative(String locale, LocaleData result) {
 
diff --git a/tools/layoutlib/bridge/tests/Android.mk b/tools/layoutlib/bridge/tests/Android.mk
index 98cade9..7a9e067 100644
--- a/tools/layoutlib/bridge/tests/Android.mk
+++ b/tools/layoutlib/bridge/tests/Android.mk
@@ -24,7 +24,13 @@
 LOCAL_MODULE := layoutlib-tests
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_JAVA_LIBRARIES := layoutlib kxml2-2.3.0 junit
+LOCAL_JAVA_LIBRARIES := layoutlib \
+			kxml2-2.3.0 \
+			icu4j \
+			layoutlib_api-prebuilt \
+			tools-common-prebuilt \
+			sdk-common \
+			junit
 
 include $(BUILD_HOST_JAVA_LIBRARY)
 
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/.gitignore b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/.gitignore
new file mode 100644
index 0000000..a2ce0dc
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/.gitignore
@@ -0,0 +1,14 @@
+.gradle
+local.properties
+.idea
+.DS_Store
+*.iml
+# We need the built .class files to load custom views and R class.
+# The only way to negate an exclusion is by including every single parent
+# and excluding all children of those parents.
+
+/build/*
+!/build/intermediates/
+
+/build/intermediates/*
+!/build/intermediates/classes/
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build.gradle b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build.gradle
new file mode 100644
index 0000000..80be12d
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build.gradle
@@ -0,0 +1,43 @@
+buildscript {
+    repositories {
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:0.12.+'
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        jcenter()
+    }
+}
+
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 20
+    buildToolsVersion '20'
+    defaultConfig {
+        applicationId 'com.android.layoutlib.test.myapplication'
+        minSdkVersion 19
+        targetSdkVersion 20
+        versionCode 1
+        versionName '1.0'
+    }
+    buildTypes {
+        release {
+            runProguard false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+    productFlavors {
+    }
+}
+
+dependencies {
+    compile fileTree(dir: 'libs', include: ['*.jar'])
+}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/BuildConfig.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/BuildConfig.class
new file mode 100644
index 0000000..2b4f7bf
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/BuildConfig.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class
new file mode 100644
index 0000000..d252462
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$attr.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$attr.class
new file mode 100644
index 0000000..9bab801
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$attr.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$dimen.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$dimen.class
new file mode 100644
index 0000000..7ad8605
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$dimen.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$drawable.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$drawable.class
new file mode 100644
index 0000000..e9e0a33
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$drawable.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class
new file mode 100644
index 0000000..d109302
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class
new file mode 100644
index 0000000..816ecc8
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class
new file mode 100644
index 0000000..b034b75
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class
new file mode 100644
index 0000000..f86b1d3
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class
new file mode 100644
index 0000000..8bbae90
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class
new file mode 100644
index 0000000..8af745d
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle.properties b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle.properties
new file mode 100644
index 0000000..5d08ba7
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Settings specified in this file will override any Gradle settings
+# configured through the IDE.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.jar b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.properties b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..5de946b
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew.bat b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off

+@rem ##########################################################################

+@rem

+@rem  Gradle startup script for Windows

+@rem

+@rem ##########################################################################

+

+@rem Set local scope for the variables with windows NT shell

+if "%OS%"=="Windows_NT" setlocal

+

+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

+set DEFAULT_JVM_OPTS=

+

+set DIRNAME=%~dp0

+if "%DIRNAME%" == "" set DIRNAME=.

+set APP_BASE_NAME=%~n0

+set APP_HOME=%DIRNAME%

+

+@rem Find java.exe

+if defined JAVA_HOME goto findJavaFromJavaHome

+

+set JAVA_EXE=java.exe

+%JAVA_EXE% -version >NUL 2>&1

+if "%ERRORLEVEL%" == "0" goto init

+

+echo.

+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:findJavaFromJavaHome

+set JAVA_HOME=%JAVA_HOME:"=%

+set JAVA_EXE=%JAVA_HOME%/bin/java.exe

+

+if exist "%JAVA_EXE%" goto init

+

+echo.

+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:init

+@rem Get command-line arguments, handling Windowz variants

+

+if not "%OS%" == "Windows_NT" goto win9xME_args

+if "%@eval[2+2]" == "4" goto 4NT_args

+

+:win9xME_args

+@rem Slurp the command line arguments.

+set CMD_LINE_ARGS=

+set _SKIP=2

+

+:win9xME_args_slurp

+if "x%~1" == "x" goto execute

+

+set CMD_LINE_ARGS=%*

+goto execute

+

+:4NT_args

+@rem Get arguments from the 4NT Shell from JP Software

+set CMD_LINE_ARGS=%$

+

+:execute

+@rem Setup the command line

+

+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

+

+@rem Execute Gradle

+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

+

+:end

+@rem End local scope for the variables with windows NT shell

+if "%ERRORLEVEL%"=="0" goto mainEnd

+

+:fail

+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of

+rem the _cmd.exe /c_ return code!

+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1

+exit /b 1

+

+:mainEnd

+if "%OS%"=="Windows_NT" endlocal

+

+:omega

diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/proguard-rules.pro b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/proguard-rules.pro
new file mode 100644
index 0000000..b0fcd2d
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /usr/local/google/home/deepanshu/ssd/sdk_out/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/androidTest/java/com/android/layoulib/test/myapplication/ApplicationTest.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/androidTest/java/com/android/layoulib/test/myapplication/ApplicationTest.java
new file mode 100644
index 0000000..7304af1
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/androidTest/java/com/android/layoulib/test/myapplication/ApplicationTest.java
@@ -0,0 +1,13 @@
+package com.android.layoulib.test.myapplication;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
+ */
+public class ApplicationTest extends ApplicationTestCase<Application> {
+    public ApplicationTest() {
+        super(Application.class);
+    }
+}
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/AndroidManifest.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..2067474
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.layoutlib.test.myapplication" >
+<!-- If changing package here, update LayoutLibCallBack in tests. -->
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name="com.android.layoutlib.test.myapplication.MyActivity"
+            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/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/MyActivity.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/MyActivity.java
new file mode 100644
index 0000000..59de457
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/MyActivity.java
@@ -0,0 +1,35 @@
+package com.android.layoutlib.test.myapplication;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+
+public class MyActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity);
+    }
+
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        // Inflate the menu; this adds items to the action bar if it is present.
+        getMenuInflater().inflate(R.menu.my, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        // Handle action bar item clicks here. The action bar will
+        // automatically handle clicks on the Home/Up button, so long
+        // as you specify a parent activity in AndroidManifest.xml.
+        int id = item.getItemId();
+        if (id == R.id.action_settings) {
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/ic_launcher.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/ic_launcher.xml
new file mode 100644
index 0000000..67481d4
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/ic_launcher.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="#ff0000" />
+    <size
+        android:width="20dp"
+        android:height="20dp" />
+</shape>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/activity.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/activity.xml
new file mode 100644
index 0000000..97d1983
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/activity.xml
@@ -0,0 +1,21 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    tools:context=".MyActivity">
+
+    <TextView
+        android:text="@string/hello_world"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/text1"/>
+
+    <include layout="@layout/layout"
+        android:layout_below="@+id/text1"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content" />
+</RelativeLayout>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml
new file mode 100644
index 0000000..2704c07
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical" android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Some text"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/menu/my.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/menu/my.xml
new file mode 100644
index 0000000..bea58cc
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/menu/my.xml
@@ -0,0 +1,8 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context=".MyActivity" >
+    <item android:id="@+id/action_settings"
+        android:title="@string/action_settings"
+        android:orderInCategory="100"
+        android:showAsAction="never" />
+</menu>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/dimens.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..47c8224
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+<resources>
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/strings.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/strings.xml
new file mode 100644
index 0000000..2b7083b
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="app_name">My Application</string>
+    <string name="hello_world">Hello world!</string>
+    <string name="action_settings">Settings</string>
+
+</resources>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/styles.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/styles.xml
new file mode 100644
index 0000000..ff6c9d2
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+    </style>
+
+</resources>
diff --git a/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java b/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java
index ec4edac..d20fb14 100644
--- a/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java
+++ b/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java
@@ -23,16 +23,6 @@
  */
 public class Matrix_DelegateTest extends TestCase {
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
     public void testIdentity() {
         Matrix m1 = new Matrix();
 
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
index 865a008..92fcf90 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
@@ -24,17 +24,6 @@
 import junit.framework.TestCase;
 
 public class BridgeXmlBlockParserTest extends TestCase {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
     public void testXmlBlockParser() throws Exception {
 
         XmlPullParser parser = ParserFactory.create(
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
new file mode 100644
index 0000000..31b3e25
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -0,0 +1,322 @@
+/*
+ * 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.layoutlib.bridge.intensive;
+
+import com.android.annotations.NonNull;
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.RenderSession;
+import com.android.ide.common.rendering.api.Result;
+import com.android.ide.common.rendering.api.SessionParams;
+import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
+import com.android.ide.common.resources.FrameworkResources;
+import com.android.ide.common.resources.ResourceItem;
+import com.android.ide.common.resources.ResourceRepository;
+import com.android.ide.common.resources.ResourceResolver;
+import com.android.ide.common.resources.configuration.FolderConfiguration;
+import com.android.io.FolderWrapper;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
+import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
+import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
+import com.android.utils.ILogger;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Comparator;
+
+import static org.junit.Assert.fail;
+
+/**
+ * This is a set of tests that loads all the framework resources and a project checked in this
+ * test's resources. The main dependencies
+ * are:
+ * 1. Fonts directory.
+ * 2. Framework Resources.
+ * 3. App resources.
+ * 4. build.prop file
+ *
+ * These are configured by two variables set in the system properties.
+ *
+ * 1. platform.dir: This is the directory for the current platform in the built SDK
+ *     (.../sdk/platforms/android-<version>).
+ *
+ *     The fonts are platform.dir/data/fonts.
+ *     The Framework resources are platform.dir/data/res.
+ *     build.prop is at platform.dir/build.prop.
+ *
+ * 2. test_res.dir: This is the directory for the resources of the test. If not specified, this
+ *     falls back to getClass().getProtectionDomain().getCodeSource().getLocation()
+ *
+ *     The app resources are at: test_res.dir/testApp/MyApplication/app/src/main/res
+ */
+public class Main {
+
+    private static final String PLATFORM_DIR_PROPERTY = "platform.dir";
+    private static final String RESOURCE_DIR_PROPERTY = "test_res.dir";
+
+    private static final String PLATFORM_DIR;
+    private static final String TEST_RES_DIR;
+    private static final String APP_TEST_RES = "/testApp/MyApplication/src/main/res";
+
+    private LayoutLog mLayoutLibLog;
+    private FrameworkResources mFrameworkRepo;
+    private ResourceRepository mProjectResources;
+    private ILogger mLogger;
+    private Bridge mBridge;
+
+    static {
+        // Test that System Properties are properly set.
+        PLATFORM_DIR = getPlatformDir();
+        if (PLATFORM_DIR == null) {
+            fail(String.format("System Property %1$s not properly set. The value is %2$s",
+                    PLATFORM_DIR_PROPERTY, System.getProperty(PLATFORM_DIR_PROPERTY)));
+        }
+
+        TEST_RES_DIR = getTestResDir();
+        if (TEST_RES_DIR == null) {
+            fail(String.format("System property %1$s.dir not properly set. The value is %2$s",
+                    RESOURCE_DIR_PROPERTY, System.getProperty(RESOURCE_DIR_PROPERTY)));
+        }
+    }
+
+    private static String getPlatformDir() {
+        String platformDir = System.getProperty(PLATFORM_DIR_PROPERTY);
+        if (platformDir != null && !platformDir.isEmpty() && new File(platformDir).isDirectory()) {
+            return platformDir;
+        }
+        // System Property not set. Try to find the directory in the build directory.
+        String out = System.getenv("ANDROID_HOST_OUT");
+        if (out == null || out.isEmpty() || !new File(out).isDirectory()) {
+            // Can't find the out directory.
+            return null;
+        }
+        File sdkDir = new File(out, "sdk" + File.separator + "sdk");
+        if (!sdkDir.isDirectory()) {
+            // The directory we thought that should contain the sdk is not a directory.
+            return null;
+        }
+        File[] possibleSdks = sdkDir.listFiles(new FileFilter() {
+            @Override
+            public boolean accept(File path) {
+                return path.isDirectory() && path.getAbsolutePath().contains("android-sdk");
+            }
+        });
+        for (File possibleSdk : possibleSdks) {
+            File platformsDir = new File(possibleSdk, "platforms");
+            File[] platforms = platformsDir.listFiles(new FileFilter() {
+                @Override
+                public boolean accept(File path) {
+                    return path.isDirectory() && path.getName().startsWith("android-");
+                }
+            });
+            if (platforms == null || platforms.length == 0) {
+                continue;
+            }
+            Arrays.sort(platforms, new Comparator<File>() {
+                // Codenames before ints. Higher APIs precede lower.
+                @Override
+                public int compare(File o1, File o2) {
+                    final int MAX_VALUE = 1000;
+                    String suffix1 = o1.getName().substring("android-".length());
+                    String suffix2 = o2.getName().substring("android-".length());
+                    int suff1, suff2;
+                    try {
+                        suff1 = Integer.parseInt(suffix1);
+                    } catch (NumberFormatException e) {
+                        suff1 = MAX_VALUE;
+                    }
+                    try {
+                        suff2 = Integer.parseInt(suffix2);
+                    } catch (NumberFormatException e) {
+                        suff2 = MAX_VALUE;
+                    }
+                    if (suff1 != MAX_VALUE || suff2 != MAX_VALUE) {
+                        return suff2 - suff1;
+                    }
+                    return suffix2.compareTo(suffix1);
+                }
+            });
+            return platforms[0].getAbsolutePath();
+        }
+        return null;
+    }
+
+    private static String getTestResDir() {
+        String resourceDir = System.getProperty(RESOURCE_DIR_PROPERTY);
+        if (resourceDir != null && !resourceDir.isEmpty() && new File(resourceDir).isDirectory()) {
+            return resourceDir;
+        }
+        // TEST_RES_DIR not explicitly set. Fallback to the class's source location.
+        try {
+            URL location = Main.class.getProtectionDomain().getCodeSource().getLocation();
+            return new File(location.getPath()).exists() ? location.getPath() : null;
+        } catch (NullPointerException e) {
+            // Prevent a lot of null checks by just catching the exception.
+            return null;
+        }
+    }
+    /**
+     * Initialize the bridge and the resource maps.
+     */
+    @Before
+    public void setUp() {
+        File data_dir = new File(PLATFORM_DIR, "data");
+        File res = new File(data_dir, "res");
+        mFrameworkRepo = new FrameworkResources(new FolderWrapper(res));
+        mFrameworkRepo.loadResources();
+        mFrameworkRepo.loadPublicResources(getLogger());
+
+        mProjectResources =
+                new ResourceRepository(new FolderWrapper(TEST_RES_DIR + APP_TEST_RES), false) {
+            @NonNull
+            @Override
+            protected ResourceItem createResourceItem(String name) {
+                return new ResourceItem(name);
+            }
+        };
+        mProjectResources.loadResources();
+
+        File fontLocation = new File(data_dir, "fonts");
+        File buildProp = new File(PLATFORM_DIR, "build.prop");
+        File attrs = new File(res, "values" + File.separator + "attrs.xml");
+        mBridge = new Bridge();
+        mBridge.init(ConfigGenerator.loadProperties(buildProp), fontLocation,
+                ConfigGenerator.getEnumMap(attrs), getLayoutLog());
+    }
+
+    /**
+     * Create a new rendering session and test that rendering /layout/activity.xml on nexus 5
+     * doesn't throw any exceptions.
+     */
+    @Test
+    public void testRendering() throws ClassNotFoundException {
+        // Create the layout pull parser.
+        LayoutPullParser parser = new LayoutPullParser(APP_TEST_RES + "/layout/activity.xml");
+        // Create LayoutLibCallback.
+        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
+        layoutLibCallback.initResources();
+        // TODO: Set up action bar handler properly to test menu rendering.
+        // Create session params.
+        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5, layoutLibCallback);
+        RenderSession session = mBridge.createSession(params);
+        if (!session.getResult().isSuccess()) {
+            getLogger().error(session.getResult().getException(),
+                    session.getResult().getErrorMessage());
+        }
+        // Render the session with a timeout of 50s.
+        Result renderResult = session.render(50000);
+        if (!renderResult.isSuccess()) {
+            getLogger().error(session.getResult().getException(),
+                    session.getResult().getErrorMessage());
+        }
+    }
+
+    /**
+     * Uses Theme.Material and Target sdk version as 21.
+     */
+    private SessionParams getSessionParams(LayoutPullParser layoutParser,
+            ConfigGenerator configGenerator, LayoutLibTestCallback layoutLibCallback) {
+        FolderConfiguration config = configGenerator.getFolderConfig();
+        ResourceResolver resourceResolver =
+                ResourceResolver.create(mProjectResources.getConfiguredResources(config),
+                        mFrameworkRepo.getConfiguredResources(config), "Theme.Material", false);
+
+        return new SessionParams(
+                layoutParser,
+                RenderingMode.NORMAL,
+                null /*used for caching*/,
+                configGenerator.getHardwareConfig(),
+                resourceResolver,
+                layoutLibCallback,
+                0,
+                21, // TODO: Make it more configurable to run tests for various versions.
+                getLayoutLog());
+    }
+
+    private LayoutLog getLayoutLog() {
+        if (mLayoutLibLog == null) {
+            mLayoutLibLog = new LayoutLog() {
+                @Override
+                public void warning(String tag, String message, Object data) {
+                    System.out.println("Warning " + tag + ": " + message);
+                    fail(message);
+                }
+
+                @Override
+                public void fidelityWarning(String tag, String message, Throwable throwable,
+                        Object data) {
+                    System.out.println("FidelityWarning " + tag + ": " + message);
+                    if (throwable != null) {
+                        throwable.printStackTrace();
+                    }
+                    fail(message);
+                }
+
+                @Override
+                public void error(String tag, String message, Object data) {
+                    System.out.println("Error " + tag + ": " + message);
+                    fail(message);
+                }
+
+                @Override
+                public void error(String tag, String message, Throwable throwable, Object data) {
+                    System.out.println("Error " + tag + ": " + message);
+                    if (throwable != null) {
+                        throwable.printStackTrace();
+                    }
+                    fail(message);
+                }
+            };
+        }
+        return mLayoutLibLog;
+    }
+
+    private ILogger getLogger() {
+        if (mLogger == null) {
+            mLogger = new ILogger() {
+                @Override
+                public void error(Throwable t, String msgFormat, Object... args) {
+                    if (t != null) {
+                        t.printStackTrace();
+                    }
+                    fail(String.format(msgFormat, args));
+                }
+
+                @Override
+                public void warning(String msgFormat, Object... args) {
+                    fail(String.format(msgFormat, args));
+                }
+
+                @Override
+                public void info(String msgFormat, Object... args) {
+                    // pass.
+                }
+
+                @Override
+                public void verbose(String msgFormat, Object... args) {
+                    // pass.
+                }
+            };
+        }
+        return mLogger;
+    }
+}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java
new file mode 100644
index 0000000..a5c3202
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java
@@ -0,0 +1,294 @@
+/*
+ * 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.layoutlib.bridge.intensive.setup;
+
+import com.android.ide.common.rendering.api.HardwareConfig;
+import com.android.ide.common.resources.configuration.CountryCodeQualifier;
+import com.android.ide.common.resources.configuration.DensityQualifier;
+import com.android.ide.common.resources.configuration.FolderConfiguration;
+import com.android.ide.common.resources.configuration.KeyboardStateQualifier;
+import com.android.ide.common.resources.configuration.LanguageQualifier;
+import com.android.ide.common.resources.configuration.LayoutDirectionQualifier;
+import com.android.ide.common.resources.configuration.NavigationMethodQualifier;
+import com.android.ide.common.resources.configuration.NetworkCodeQualifier;
+import com.android.ide.common.resources.configuration.NightModeQualifier;
+import com.android.ide.common.resources.configuration.RegionQualifier;
+import com.android.ide.common.resources.configuration.ScreenDimensionQualifier;
+import com.android.ide.common.resources.configuration.ScreenOrientationQualifier;
+import com.android.ide.common.resources.configuration.ScreenRatioQualifier;
+import com.android.ide.common.resources.configuration.ScreenSizeQualifier;
+import com.android.ide.common.resources.configuration.TextInputMethodQualifier;
+import com.android.ide.common.resources.configuration.TouchScreenQualifier;
+import com.android.ide.common.resources.configuration.UiModeQualifier;
+import com.android.ide.common.resources.configuration.VersionQualifier;
+import com.android.resources.Density;
+import com.android.resources.Keyboard;
+import com.android.resources.KeyboardState;
+import com.android.resources.Navigation;
+import com.android.resources.NightMode;
+import com.android.resources.ScreenOrientation;
+import com.android.resources.ScreenRatio;
+import com.android.resources.ScreenSize;
+import com.android.resources.TouchScreen;
+import com.android.resources.UiMode;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Properties;
+
+import com.google.android.collect.Maps;
+
+/**
+ * Provides {@link FolderConfiguration} and {@link HardwareConfig} for various devices. Also
+ * provides utility methods to parse build.prop and attrs.xml to generate the appropriate maps.
+ */
+@SuppressWarnings("UnusedDeclaration") // For the pre-configured nexus generators.
+public class ConfigGenerator {
+
+    public static final ConfigGenerator NEXUS_4 = new ConfigGenerator();
+
+    public static final ConfigGenerator NEXUS_5 = new ConfigGenerator()
+                                                        .setScreenHeight(1920)
+                                                        .setScreenWidth(1080)
+                                                        .setXdpi(445)
+                                                        .setYdpi(445)
+                                                        .setOrientation(ScreenOrientation.PORTRAIT)
+                                                        .setDensity(Density.XXHIGH)
+                                                        .setRatio(ScreenRatio.NOTLONG)
+                                                        .setSize(ScreenSize.NORMAL)
+                                                        .setKeyboard(Keyboard.NOKEY)
+                                                        .setTouchScreen(TouchScreen.FINGER)
+                                                        .setKeyboardState(KeyboardState.SOFT)
+                                                        .setSoftButtons(true)
+                                                        .setNavigation(Navigation.NONAV);
+
+    public static final ConfigGenerator NEXUS_7 = new ConfigGenerator()
+                                                        .setScreenHeight(1920)
+                                                        .setScreenWidth(1200)
+                                                        .setXdpi(323)
+                                                        .setYdpi(323)
+                                                        .setOrientation(ScreenOrientation.PORTRAIT)
+                                                        .setDensity(Density.XHIGH)
+                                                        .setRatio(ScreenRatio.NOTLONG)
+                                                        .setSize(ScreenSize.LARGE)
+                                                        .setKeyboard(Keyboard.NOKEY)
+                                                        .setTouchScreen(TouchScreen.FINGER)
+                                                        .setKeyboardState(KeyboardState.SOFT)
+                                                        .setSoftButtons(true)
+                                                        .setNavigation(Navigation.NONAV);
+
+    public static final ConfigGenerator NEXUS_10 = new ConfigGenerator()
+                                                        .setScreenHeight(1600)
+                                                        .setScreenWidth(2560)
+                                                        .setXdpi(300)
+                                                        .setYdpi(300)
+                                                        .setOrientation(ScreenOrientation.LANDSCAPE)
+                                                        .setDensity(Density.XHIGH)
+                                                        .setRatio(ScreenRatio.NOTLONG)
+                                                        .setSize(ScreenSize.XLARGE)
+                                                        .setKeyboard(Keyboard.NOKEY)
+                                                        .setTouchScreen(TouchScreen.FINGER)
+                                                        .setKeyboardState(KeyboardState.SOFT)
+                                                        .setSoftButtons(true)
+                                                        .setNavigation(Navigation.NONAV);
+
+    private static final String TAG_ATTR = "attr";
+    private static final String TAG_ENUM = "enum";
+    private static final String TAG_FLAG = "flag";
+    private static final String ATTR_NAME = "name";
+    private static final String ATTR_VALUE = "value";
+
+    // Device Configuration. Defaults are for a Nexus 4 device.
+    private int mScreenHeight = 1280;
+    private int mScreenWidth = 768;
+    private int mXdpi = 320;
+    private int mYdpi = 320;
+    private ScreenOrientation mOrientation = ScreenOrientation.PORTRAIT;
+    private Density mDensity = Density.XHIGH;
+    private ScreenRatio mRatio = ScreenRatio.NOTLONG;
+    private ScreenSize mSize = ScreenSize.NORMAL;
+    private Keyboard mKeyboard = Keyboard.NOKEY;
+    private TouchScreen mTouchScreen = TouchScreen.FINGER;
+    private KeyboardState mKeyboardState = KeyboardState.SOFT;
+    private boolean mSoftButtons = true;
+    private Navigation mNavigation = Navigation.NONAV;
+
+    public FolderConfiguration getFolderConfig() {
+        FolderConfiguration config = new FolderConfiguration();
+        config.createDefault();
+        config.setDensityQualifier(new DensityQualifier(mDensity));
+        config.setNavigationMethodQualifier(new NavigationMethodQualifier(mNavigation));
+        if (mScreenWidth > mScreenHeight) {
+            config.setScreenDimensionQualifier(new ScreenDimensionQualifier(mScreenWidth,
+                    mScreenHeight));
+        } else {
+            config.setScreenDimensionQualifier(new ScreenDimensionQualifier(mScreenHeight,
+                    mScreenWidth));
+        }
+        config.setScreenRatioQualifier(new ScreenRatioQualifier(mRatio));
+        config.setScreenSizeQualifier(new ScreenSizeQualifier(mSize));
+        config.setTextInputMethodQualifier(new TextInputMethodQualifier(mKeyboard));
+        config.setTouchTypeQualifier(new TouchScreenQualifier(mTouchScreen));
+        config.setKeyboardStateQualifier(new KeyboardStateQualifier(mKeyboardState));
+        config.setScreenOrientationQualifier(new ScreenOrientationQualifier(mOrientation));
+
+        config.updateScreenWidthAndHeight();
+
+        // some default qualifiers.
+        config.setUiModeQualifier(new UiModeQualifier(UiMode.NORMAL));
+        config.setNightModeQualifier(new NightModeQualifier(NightMode.NOTNIGHT));
+        config.setCountryCodeQualifier(new CountryCodeQualifier());
+        config.setLanguageQualifier(new LanguageQualifier());
+        config.setLayoutDirectionQualifier(new LayoutDirectionQualifier());
+        config.setNetworkCodeQualifier(new NetworkCodeQualifier());
+        config.setRegionQualifier(new RegionQualifier());
+        config.setVersionQualifier(new VersionQualifier());
+        return config;
+    }
+
+    public HardwareConfig getHardwareConfig() {
+        return new HardwareConfig(mScreenWidth, mScreenHeight, mDensity, mXdpi, mYdpi, mSize,
+                mOrientation, mSoftButtons);
+    }
+
+    public static Map<String, String> loadProperties(File path) {
+        Properties p = new Properties();
+        Map<String, String> map = Maps.newHashMap();
+        try {
+            p.load(new FileInputStream(path));
+            for (String key : p.stringPropertyNames()) {
+                map.put(key, p.getProperty(key));
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return map;
+    }
+
+    public static Map<String, Map<String, Integer>> getEnumMap(File path) {
+        Map<String, Map<String, Integer>> map = Maps.newHashMap();
+        try {
+            XmlPullParser xmlPullParser = XmlPullParserFactory.newInstance().newPullParser();
+            xmlPullParser.setInput(new FileInputStream(path), null);
+            int eventType = xmlPullParser.getEventType();
+            String attr = null;
+            while (eventType != XmlPullParser.END_DOCUMENT) {
+                if (eventType == XmlPullParser.START_TAG) {
+                    if (TAG_ATTR.equals(xmlPullParser.getName())) {
+                        attr = xmlPullParser.getAttributeValue(null, ATTR_NAME);
+                    } else if (TAG_ENUM.equals(xmlPullParser.getName())
+                            || TAG_FLAG.equals(xmlPullParser.getName())) {
+                        String name = xmlPullParser.getAttributeValue(null, ATTR_NAME);
+                        String value = xmlPullParser.getAttributeValue(null, ATTR_VALUE);
+                        // Integer.decode cannot handle "ffffffff", see JDK issue 6624867
+                        int i = (int) (long) Long.decode(value);
+                        assert attr != null;
+                        Map<String, Integer> attributeMap = map.get(attr);
+                        if (attributeMap == null) {
+                            attributeMap = Maps.newHashMap();
+                            map.put(attr, attributeMap);
+                        }
+                        attributeMap.put(name, i);
+                    }
+                } else if (eventType == XmlPullParser.END_TAG) {
+                    if (TAG_ATTR.equals(xmlPullParser.getName())) {
+                        attr = null;
+                    }
+                }
+                eventType = xmlPullParser.next();
+            }
+        } catch (XmlPullParserException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return map;
+    }
+
+    // Methods to set the configuration values.
+
+    public ConfigGenerator setScreenHeight(int height) {
+        mScreenHeight = height;
+        return this;
+    }
+
+    public ConfigGenerator setScreenWidth(int width) {
+        mScreenWidth = width;
+        return this;
+    }
+
+    public ConfigGenerator setXdpi(int xdpi) {
+        mXdpi = xdpi;
+        return this;
+    }
+
+    public ConfigGenerator setYdpi(int ydpi) {
+        mYdpi = ydpi;
+        return this;
+    }
+
+    public ConfigGenerator setOrientation(ScreenOrientation orientation) {
+        mOrientation = orientation;
+        return this;
+    }
+
+    public ConfigGenerator setDensity(Density density) {
+        mDensity = density;
+        return this;
+    }
+
+    public ConfigGenerator setRatio(ScreenRatio ratio) {
+        mRatio = ratio;
+        return this;
+    }
+
+    public ConfigGenerator setSize(ScreenSize size) {
+        mSize = size;
+        return this;
+    }
+
+    public ConfigGenerator setKeyboard(Keyboard keyboard) {
+        mKeyboard = keyboard;
+        return this;
+    }
+
+    public ConfigGenerator setTouchScreen(TouchScreen touchScreen) {
+        mTouchScreen = touchScreen;
+        return this;
+    }
+
+    public ConfigGenerator setKeyboardState(KeyboardState state) {
+        mKeyboardState = state;
+        return this;
+    }
+
+    public ConfigGenerator setSoftButtons(boolean softButtons) {
+        mSoftButtons = softButtons;
+        return this;
+    }
+
+    public ConfigGenerator setNavigation(Navigation navigation) {
+        mNavigation = navigation;
+        return this;
+    }
+}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
new file mode 100644
index 0000000..565e881
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
@@ -0,0 +1,183 @@
+/*
+ * 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.layoutlib.bridge.intensive.setup;
+
+import com.android.SdkConstants;
+import com.android.ide.common.rendering.api.ActionBarCallback;
+import com.android.ide.common.rendering.api.AdapterBinding;
+import com.android.ide.common.rendering.api.ILayoutPullParser;
+import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.ResourceReference;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.resources.ResourceType;
+import com.android.ide.common.resources.IntArrayWrapper;
+import com.android.util.Pair;
+import com.android.utils.ILogger;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Map;
+
+import com.google.android.collect.Maps;
+
+@SuppressWarnings("deprecation") // For Pair
+public class LayoutLibTestCallback extends ClassLoader implements IProjectCallback {
+
+    private static final String PROJECT_CLASSES_LOCATION = "/testApp/MyApplication/build/intermediates/classes/debug/";
+    private static final String PACKAGE_NAME = "com.android.layoutlib.test.myapplication";
+
+    private final Map<Integer, Pair<ResourceType, String>> mProjectResources = Maps.newHashMap();
+    private final Map<IntArrayWrapper, String> mStyleableValueToNameMap = Maps.newHashMap();
+    private final Map<ResourceType, Map<String, Integer>> mResources = Maps.newHashMap();
+    private final Map<String, Class<?>> mClasses = Maps.newHashMap();
+    private final ILogger mLog;
+    private final ActionBarCallback mActionBarCallback = new ActionBarCallback();
+
+    public LayoutLibTestCallback(ILogger logger) {
+        mLog = logger;
+    }
+
+    public void initResources() throws ClassNotFoundException {
+        Class<?> rClass = loadClass(PACKAGE_NAME + ".R");
+        Class<?>[] nestedClasses = rClass.getDeclaredClasses();
+        for (Class<?> resClass : nestedClasses) {
+            final ResourceType resType = ResourceType.getEnum(resClass.getSimpleName());
+
+            if (resType != null) {
+                final Map<String, Integer> resName2Id = Maps.newHashMap();
+                mResources.put(resType, resName2Id);
+
+                for (Field field : resClass.getDeclaredFields()) {
+                    final int modifiers = field.getModifiers();
+                    if (Modifier.isStatic(modifiers)) { // May not be final in library projects
+                        final Class<?> type = field.getType();
+                        try {
+                            if (type.isArray() && type.getComponentType() == int.class) {
+                                mStyleableValueToNameMap.put(
+                                        new IntArrayWrapper((int[]) field.get(null)),
+                                        field.getName());
+                            } else if (type == int.class) {
+                                final Integer value = (Integer) field.get(null);
+                                mProjectResources.put(value, Pair.of(resType, field.getName()));
+                                resName2Id.put(field.getName(), value);
+                            } else {
+                                mLog.error(null, "Unknown field type in R class: %1$s", type);
+                            }
+                        } catch (IllegalAccessException ignored) {
+                            mLog.error(ignored, "Malformed R class: %1$s", PACKAGE_NAME + ".R");
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    protected Class<?> findClass(String name) throws ClassNotFoundException {
+        Class<?> aClass = mClasses.get(name);
+        if (aClass != null) {
+            return aClass;
+        }
+        String pathName = PROJECT_CLASSES_LOCATION.concat(name.replace('.', '/')).concat(".class");
+        InputStream classInputStream = getClass().getResourceAsStream(pathName);
+        if (classInputStream == null) {
+            throw new ClassNotFoundException("Unable to find class " + name + " at " + pathName);
+        }
+        byte[] data;
+        try {
+            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+            int nRead;
+            data = new byte[16384];
+            while ((nRead = classInputStream.read(data, 0, data.length)) != -1) {
+                buffer.write(data, 0, nRead);
+            }
+            buffer.flush();
+            data = buffer.toByteArray();
+        } catch (IOException e) {
+            // Wrap the exception with ClassNotFoundException so that caller can deal with it.
+            throw new ClassNotFoundException("Unable to load class " + name, e);
+        }
+        aClass = defineClass(name, data, 0, data.length);
+        mClasses.put(name, aClass);
+        return aClass;
+    }
+
+    @Override
+    public Object loadView(String name, Class[] constructorSignature, Object[] constructorArgs)
+            throws Exception {
+        Class<?> viewClass = findClass(name);
+        Constructor<?> viewConstructor = viewClass.getConstructor(constructorSignature);
+        viewConstructor.setAccessible(true);
+        return viewConstructor.newInstance(constructorArgs);
+    }
+
+    @Override
+    public String getNamespace() {
+        return String.format(SdkConstants.NS_CUSTOM_RESOURCES_S,
+                PACKAGE_NAME);
+    }
+
+    @Override
+    public Pair<ResourceType, String> resolveResourceId(int id) {
+        return mProjectResources.get(id);
+    }
+
+    @Override
+    public String resolveResourceId(int[] id) {
+        return mStyleableValueToNameMap.get(new IntArrayWrapper(id));
+    }
+
+    @Override
+    public Integer getResourceId(ResourceType type, String name) {
+        return mResources.get(type).get(name);
+    }
+
+    @Override
+    public ILayoutPullParser getParser(String layoutName) {
+        org.junit.Assert.fail("This method shouldn't be called by this version of LayoutLib.");
+        return null;
+    }
+
+    @Override
+    public ILayoutPullParser getParser(ResourceValue layoutResource) {
+        return new LayoutPullParser(new File(layoutResource.getValue()));
+    }
+
+    @Override
+    public Object getAdapterItemValue(ResourceReference adapterView, Object adapterCookie,
+            ResourceReference itemRef, int fullPosition, int positionPerType,
+            int fullParentPosition, int parentPositionPerType, ResourceReference viewRef,
+            ViewAttribute viewAttribute, Object defaultValue) {
+        return null;
+    }
+
+    @Override
+    public AdapterBinding getAdapterBinding(ResourceReference adapterViewRef, Object adapterCookie,
+            Object viewObject) {
+        return null;
+    }
+
+    @Override
+    public ActionBarCallback getActionBarCallback() {
+        return mActionBarCallback;
+    }
+}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java
new file mode 100644
index 0000000..c79b662
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java
@@ -0,0 +1,111 @@
+/*
+ * 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.layoutlib.bridge.intensive.setup;
+
+import com.android.ide.common.rendering.api.ILayoutPullParser;
+
+import org.kxml2.io.KXmlParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOError;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.android.SdkConstants.ATTR_IGNORE;
+import static com.android.SdkConstants.EXPANDABLE_LIST_VIEW;
+import static com.android.SdkConstants.GRID_VIEW;
+import static com.android.SdkConstants.LIST_VIEW;
+import static com.android.SdkConstants.SPINNER;
+import static com.android.SdkConstants.TOOLS_URI;
+
+public class LayoutPullParser extends KXmlParser implements ILayoutPullParser{
+
+    /**
+     * @param layoutPath Must start with '/' and be relative to test resources.
+     */
+    public LayoutPullParser(String layoutPath) {
+        assert layoutPath.startsWith("/");
+        try {
+            init(getClass().getResourceAsStream(layoutPath));
+        } catch (XmlPullParserException e) {
+            throw new IOError(e);
+        }
+    }
+
+    /**
+     * @param layoutFile Path of the layout xml file on disk.
+     */
+    public LayoutPullParser(File layoutFile) {
+        try {
+            init(new FileInputStream(layoutFile));
+        } catch (XmlPullParserException e) {
+            throw new IOError(e);
+        } catch (FileNotFoundException e) {
+            throw new IOError(e);
+        }
+    }
+
+    private void init(InputStream stream) throws XmlPullParserException {
+        setFeature(FEATURE_PROCESS_NAMESPACES, true);
+        setInput(stream, null);
+    }
+
+    @Override
+    public Object getViewCookie() {
+        // TODO: Implement this properly.
+        String name = super.getName();
+        if (name == null) {
+            return null;
+        }
+
+        // Store tools attributes if this looks like a layout we'll need adapter view
+        // bindings for in the LayoutlibCallback.
+        if (LIST_VIEW.equals(name) || EXPANDABLE_LIST_VIEW.equals(name) || GRID_VIEW.equals(name) || SPINNER.equals(name)) {
+            Map<String, String> map = null;
+            int count = getAttributeCount();
+            for (int i = 0; i < count; i++) {
+                String namespace = getAttributeNamespace(i);
+                if (namespace != null && namespace.equals(TOOLS_URI)) {
+                    String attribute = getAttributeName(i);
+                    if (attribute.equals(ATTR_IGNORE)) {
+                        continue;
+                    }
+                    if (map == null) {
+                        map = new HashMap<String, String>(4);
+                    }
+                    map.put(attribute, getAttributeValue(i));
+                }
+            }
+
+            return map;
+        }
+
+        return null;
+    }
+
+    @Override
+    @Deprecated
+    public ILayoutPullParser getParser(String layoutName) {
+        // Studio returns null.
+        return null;
+    }
+
+}
diff --git a/tools/layoutlib/create/create.iml b/tools/layoutlib/create/create.iml
new file mode 100644
index 0000000..b7e8eb3
--- /dev/null
+++ b/tools/layoutlib/create/create.iml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/tests/data" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/tests/mock_data" type="java-test-resource" />
+      <excludeFolder url="file://$MODULE_DIR$/.settings" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="asm-4.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="JUnit4" level="application" />
+  </component>
+</module>
+
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java
index 323a791..a6902a4 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java
@@ -97,7 +97,7 @@
         if (type.getSort() == Type.OBJECT) {
             String in = type.getInternalName();
             String newIn = renameInternalType(in);
-            if (newIn != in) {
+            if (!newIn.equals(in)) {
                 return Type.getType("L" + newIn + ";");
             }
         } else if (type.getSort() == Type.ARRAY) {
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
index e043d4d..9a10f79 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
@@ -341,6 +341,7 @@
                     inOutKeepClasses.size(), deps.size());
 
             for (ClassReader cr : temp.values()) {
+                visitor.setClassName(cr.getClassName());
                 cr.accept(visitor, 0 /* flags */);
             }
         }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 8fb8928..89cbaeb 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -150,7 +150,6 @@
         "com.android.internal.view.menu.MenuBuilder#createNewMenuItem",
         "com.android.internal.util.XmlUtils#convertValueToInt",
         "com.android.internal.textservice.ITextServicesManager$Stub#asInterface",
-        "android.os.SystemProperties#native_get",
         "dalvik.system.VMRuntime#newUnpaddedArray"
     };
 
@@ -198,7 +197,9 @@
         "android.graphics.Typeface",
         "android.graphics.Xfermode",
         "android.os.SystemClock",
+        "android.os.SystemProperties",
         "android.text.AndroidBidi",
+        "android.text.StaticLayout",
         "android.text.format.Time",
         "android.util.FloatMath",
         "android.view.Display",
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java
index 2016c0e..7690fcd 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java
@@ -316,9 +316,7 @@
 
             // Add it to the dependency set for the currently visited class, as needed.
             assert mCurrentDepSet != null;
-            if (mCurrentDepSet != null) {
-                mCurrentDepSet.add(className);
-            }
+            mCurrentDepSet.add(className);
         }
 
         /**
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
index ea9ce10..02f2c02 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
@@ -63,7 +63,7 @@
         String[] osDestJar = { null };
 
         if (!processArgs(log, args, osJarPath, osDestJar)) {
-            log.error("Usage: layoutlib_create [-v] [-p] output.jar input.jar ...");
+            log.error("Usage: layoutlib_create [-v] output.jar input.jar ...");
             log.error("Usage: layoutlib_create [-v] [--list-deps|--missing-deps] input.jar ...");
             System.exit(1);
         }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java
index a6aff99..4c87b3c 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java
@@ -36,6 +36,7 @@
      * Sets the default listener for all methods not specifically handled.
      * Null means to do nothing.
      */
+    @SuppressWarnings("UnusedDeclaration") // Used by Bridge by reflection for debug purposes.
     public static void setDefaultListener(MethodListener listener) {
         sDefaultListener = listener;
     }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java
index 661074c..40bd126 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java
@@ -73,7 +73,7 @@
             return mNewName;
         }
 
-        if (mOldBase != mOldName && type.equals(mOldBase)) {
+        if (!mOldBase.equals(mOldName) && type.equals(mOldBase)) {
             return mNewBase;
         }
 
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ReplaceMethodCallsAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ReplaceMethodCallsAdapter.java
index 94d5975..9c6fbac 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ReplaceMethodCallsAdapter.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ReplaceMethodCallsAdapter.java
@@ -19,11 +19,13 @@
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Locale;
 import java.util.Set;
 
 /**
@@ -42,45 +44,70 @@
 
     private static final List<MethodReplacer> METHOD_REPLACERS = new ArrayList<MethodReplacer>(2);
 
+    private static final String ANDROID_LOCALE_CLASS =
+            "com/android/layoutlib/bridge/android/AndroidLocale";
+
+    private static final String JAVA_LOCALE_CLASS = "java/util/Locale";
+    private static final Type STRING = Type.getType(String.class);
+
     // Static initialization block to initialize METHOD_REPLACERS.
     static {
         // Case 1: java.lang.System.arraycopy()
         METHOD_REPLACERS.add(new MethodReplacer() {
             @Override
             public boolean isNeeded(String owner, String name, String desc) {
-                return owner.equals("java/lang/System") && name.equals("arraycopy") &&
+                return "java/lang/System".equals(owner) && "arraycopy".equals(name) &&
                         ARRAYCOPY_DESCRIPTORS.contains(desc);
             }
 
             @Override
-            public void replace(int opcode, String owner, String name, String desc,
-                    int[] opcodeOut, String[] output) {
-                assert isNeeded(owner, name, desc) && output.length == 3
-                        && opcodeOut.length == 1;
-                opcodeOut[0] = opcode;
-                output[0] = owner;
-                output[1] = name;
-                output[2] = "(Ljava/lang/Object;ILjava/lang/Object;II)V";
+            public void replace(int[] opcode, String[] methodInformation) {
+                assert methodInformation.length == 3 && isNeeded(methodInformation[0], methodInformation[1], methodInformation[2])
+                        && opcode.length == 1;
+                methodInformation[2] = "(Ljava/lang/Object;ILjava/lang/Object;II)V";
             }
         });
 
-        // Case 2: java.util.Locale.toLanguageTag()
+        // Case 2: java.util.Locale.toLanguageTag() and java.util.Locale.getScript()
         METHOD_REPLACERS.add(new MethodReplacer() {
+
+            String LOCALE_TO_STRING = Type.getMethodDescriptor(STRING, Type.getType(Locale.class));
+
             @Override
             public boolean isNeeded(String owner, String name, String desc) {
-                return owner.equals("java/util/Locale") && name.equals("toLanguageTag") &&
-                        "()Ljava/lang/String;".equals(desc);
+                return JAVA_LOCALE_CLASS.equals(owner) && "()Ljava/lang/String;".equals(desc) &&
+                        ("toLanguageTag".equals(name) || "getScript".equals(name));
             }
 
             @Override
-            public void replace(int opcode, String owner, String name, String desc,
-                    int[] opcodeOut, String[] output) {
-                assert isNeeded(owner, name, desc) && output.length == 3
-                        && opcodeOut.length == 1;
-                opcodeOut[0] = Opcodes.INVOKESTATIC;
-                output[0] = "com/android/layoutlib/bridge/android/AndroidLocale";
-                output[1] = name;
-                output[2] = "(Ljava/util/Locale;)Ljava/lang/String;";
+            public void replace(int[] opcode, String[] methodInformation) {
+                assert methodInformation.length == 3 && isNeeded(methodInformation[0], methodInformation[1], methodInformation[2])
+                        && opcode.length == 1;
+                opcode[0] = Opcodes.INVOKESTATIC;
+                methodInformation[0] = ANDROID_LOCALE_CLASS;
+                methodInformation[2] = LOCALE_TO_STRING;
+            }
+        });
+
+        // Case 3: java.util.Locale.adjustLanguageCode() or java.util.Locale.forLanguageTag()
+        METHOD_REPLACERS.add(new MethodReplacer() {
+
+            private final String STRING_TO_STRING = Type.getMethodDescriptor(STRING, STRING);
+            private final String STRING_TO_LOCALE = Type.getMethodDescriptor(
+                    Type.getType(Locale.class), STRING);
+
+            @Override
+            public boolean isNeeded(String owner, String name, String desc) {
+                return JAVA_LOCALE_CLASS.equals(owner) &&
+                        ("adjustLanguageCode".equals(name) && desc.equals(STRING_TO_STRING) ||
+                        "forLanguageTag".equals(name) && desc.equals(STRING_TO_LOCALE));
+            }
+
+            @Override
+            public void replace(int[] opcode, String[] methodInformation) {
+                assert methodInformation.length == 3 && isNeeded(methodInformation[0], methodInformation[1], methodInformation[2])
+                        && opcode.length == 1;
+                methodInformation[0] = ANDROID_LOCALE_CLASS;
             }
         });
     }
@@ -112,16 +139,15 @@
 
         @Override
         public void visitMethodInsn(int opcode, String owner, String name, String desc) {
-            // Check if method is a specialized version of java.lang.System.arrayCopy
             for (MethodReplacer replacer : METHOD_REPLACERS) {
                 if (replacer.isNeeded(owner, name, desc)) {
-                    String[] output = new String[3];
-                    int[] opcodeOut = new int[1];
-                    replacer.replace(opcode, owner, name, desc, opcodeOut, output);
+                    String[] methodInformation = {owner, name, desc};
+                    int[] opcodeOut = {opcode};
+                    replacer.replace(opcodeOut, methodInformation);
                     opcode = opcodeOut[0];
-                    owner = output[0];
-                    name = output[1];
-                    desc = output[2];
+                    owner = methodInformation[0];
+                    name = methodInformation[1];
+                    desc = methodInformation[2];
                     break;
                 }
             }
@@ -133,14 +159,15 @@
         public boolean isNeeded(String owner, String name, String desc);
 
         /**
-         * This method must update the values of the output arrays with the new values of method
-         * attributes - opcode, owner, name and desc.
-         * @param opcodeOut An array that will contain the new value of the opcode. The size of
-         *                  the array must be 1.
-         * @param output An array that will contain the new values of the owner, name and desc in
-         *               that order. The size of the array must be 3.
+         * This method must update the arrays with the new values of the method attributes -
+         * opcode, owner, name and desc.
+         * @param opcode This array should contain the original value of the opcode. The value is
+         *               modified by the method if needed. The size of the array must be 1.
+         *
+         * @param methodInformation This array should contain the original values of the method
+         *                          attributes - owner, name and desc in that order. The values
+         *                          may be modified as needed. The size of the array must be 3.
          */
-        public void replace(int opcode, String owner, String name, String desc, int[] opcodeOut,
-                String[] output);
+        public void replace(int[] opcode, String[] methodInformation);
     }
 }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
index 51e7535..416b73a 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
@@ -29,8 +29,8 @@
  */
 class StubMethodAdapter extends MethodVisitor {
 
-    private static String CONSTRUCTOR = "<init>";
-    private static String CLASS_INIT = "<clinit>";
+    private static final String CONSTRUCTOR = "<init>";
+    private static final String CLASS_INIT = "<clinit>";
 
     /** The parent method writer */
     private MethodVisitor mParentVisitor;
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
index 0b869a5..d9ecf98 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
@@ -17,7 +17,6 @@
 package com.android.tools.layoutlib.create;
 
 import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Type;
@@ -136,13 +135,6 @@
         }
     }
 
-    /* Visits a field. Makes it public. */
-    @Override
-    public FieldVisitor visitField(int access, String name, String desc, String signature,
-            Object value) {
-        return super.visitField(access, name, desc, signature, value);
-    }
-
     /**
      * Extracts the return {@link Type} of this descriptor.
      */
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java
index 94aad1d..648cea4 100644
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java
+++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java
@@ -116,9 +116,16 @@
 
                     // Check that the native method does NOT have the new annotation
                     Method[] m = clazz2.getDeclaredMethods();
-                    assertEquals("native_instance", m[2].getName());
-                    assertTrue(Modifier.isNative(m[2].getModifiers()));
-                    Annotation[] a = m[2].getAnnotations();
+                    Method nativeInstanceMethod = null;
+                    for (Method method : m) {
+                        if ("native_instance".equals(method.getName())) {
+                            nativeInstanceMethod = method;
+                            break;
+                        }
+                    }
+                    assertNotNull(nativeInstanceMethod);
+                    assertTrue(Modifier.isNative(nativeInstanceMethod.getModifiers()));
+                    Annotation[] a = nativeInstanceMethod.getAnnotations();
                     assertEquals(0, a.length);
                 }
             };
@@ -184,9 +191,16 @@
 
                      // Check that the native method now has the new annotation and is not native
                      Method[] m = clazz2.getDeclaredMethods();
-                     assertEquals("native_instance", m[2].getName());
-                     assertFalse(Modifier.isNative(m[2].getModifiers()));
-                     Annotation[] a = m[2].getAnnotations();
+                     Method nativeInstanceMethod = null;
+                     for (Method method : m) {
+                         if ("native_instance".equals(method.getName())) {
+                             nativeInstanceMethod = method;
+                             break;
+                         }
+                     }
+                     assertNotNull(nativeInstanceMethod);
+                     assertFalse(Modifier.isNative(nativeInstanceMethod.getModifiers()));
+                     Annotation[] a = nativeInstanceMethod.getAnnotations();
                      assertEquals("LayoutlibDelegate", a[0].annotationType().getSimpleName());
                 }
             };
@@ -237,13 +251,8 @@
                     assertEquals(4+10+20, callGet(o2, 10, 20));
                     assertEquals(1+10+20, callGet_Original(o2, 10, 20));
 
-                    // The original Outer has a private method that is
-                    // delegated. We should be able to call both the delegate
-                    // and the original (which is now public).
-                    assertEquals("outerPrivateMethod",
-                                 callMethod(o2, "privateMethod_Original", false /*makePublic*/));
-
-                    // The original method is private, so by default we can't access it
+                    // The original Outer has a private method,
+                    // so by default we can't access it.
                     boolean gotIllegalAccessException = false;
                     try {
                          callMethod(o2, "privateMethod", false /*makePublic*/);
@@ -251,9 +260,18 @@
                         gotIllegalAccessException = true;
                     }
                     assertTrue(gotIllegalAccessException);
-                    // Try again, but now making it accessible
-                    assertEquals("outerPrivate_Delegate",
-                            callMethod(o2, "privateMethod", true /*makePublic*/));
+
+                    // The private method from original Outer has been
+                    // delegated. The delegate generated should have the
+                    // same access.
+                    gotIllegalAccessException = false;
+                    try {
+                        assertEquals("outerPrivateMethod",
+                                callMethod(o2, "privateMethod_Original", false /*makePublic*/));
+                    } catch (IllegalAccessException e) {
+                        gotIllegalAccessException = true;
+                    }
+                    assertTrue(gotIllegalAccessException);
 
                     // Check the inner class. Since it's not a static inner class, we need
                     // to use the hidden constructor that takes the outer class as first parameter.
diff --git a/tools/obbtool/Android.mk b/tools/obbtool/Android.mk
index 99a5671..9ff56d6 100644
--- a/tools/obbtool/Android.mk
+++ b/tools/obbtool/Android.mk
@@ -13,7 +13,7 @@
 LOCAL_SRC_FILES := \
 	Main.cpp
 
-LOCAL_CFLAGS := -Wall -Werror -Wno-mismatched-tags
+LOCAL_CFLAGS := -Wall -Werror
 
 #LOCAL_C_INCLUDES +=
 
@@ -36,7 +36,7 @@
 
 LOCAL_MODULE := pbkdf2gen
 LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS := -Wall -Werror -Wno-mismatched-tags
+LOCAL_CFLAGS := -Wall -Werror
 LOCAL_SRC_FILES := pbkdf2gen.cpp
 LOCAL_LDLIBS += -ldl
 LOCAL_C_INCLUDES := external/openssl/include $(LOCAL_C_INCLUDES)