Merge "Ignore the checksum when comparing RAs for equality." into nyc-dev
diff --git a/Android.mk b/Android.mk
index 4dc5fd34..165aed9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -117,6 +117,7 @@
 	core/java/android/bluetooth/IBluetoothManager.aidl \
 	core/java/android/bluetooth/IBluetoothManagerCallback.aidl \
 	core/java/android/bluetooth/IBluetoothPbap.aidl \
+	core/java/android/bluetooth/IBluetoothPbapClient.aidl \
 	core/java/android/bluetooth/IBluetoothMap.aidl \
 	core/java/android/bluetooth/IBluetoothSap.aidl \
 	core/java/android/bluetooth/IBluetoothStateChangeCallback.aidl \
@@ -413,6 +414,8 @@
 	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/IImsExternalCallStateListener.aidl \
+        telephony/java/com/android/ims/internal/IImsMultiEndpoint.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 \
diff --git a/api/current.txt b/api/current.txt
index e253ae1..1820dd4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3442,7 +3442,7 @@
     method public android.view.View getCurrentFocus();
     method public android.app.FragmentManager getFragmentManager();
     method public android.content.Intent getIntent();
-    method public deprecated java.lang.Object getLastNonConfigurationInstance();
+    method public java.lang.Object getLastNonConfigurationInstance();
     method public android.view.LayoutInflater getLayoutInflater();
     method public android.app.LoaderManager getLoaderManager();
     method public java.lang.String getLocalClassName();
@@ -3543,7 +3543,7 @@
     method protected void onRestoreInstanceState(android.os.Bundle);
     method public void onRestoreInstanceState(android.os.Bundle, android.os.PersistableBundle);
     method protected void onResume();
-    method public deprecated java.lang.Object onRetainNonConfigurationInstance();
+    method public java.lang.Object onRetainNonConfigurationInstance();
     method protected void onSaveInstanceState(android.os.Bundle);
     method public void onSaveInstanceState(android.os.Bundle, android.os.PersistableBundle);
     method public boolean onSearchRequested(android.view.SearchEvent);
@@ -5979,6 +5979,7 @@
     field public static final int ENCRYPTION_STATUS_ACTIVATING = 2; // 0x2
     field public static final int ENCRYPTION_STATUS_ACTIVE = 3; // 0x3
     field public static final int ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY = 4; // 0x4
+    field public static final int ENCRYPTION_STATUS_ACTIVE_PER_USER = 5; // 0x5
     field public static final int ENCRYPTION_STATUS_INACTIVE = 1; // 0x1
     field public static final int ENCRYPTION_STATUS_UNSUPPORTED = 0; // 0x0
     field public static final java.lang.String EXTRA_ADD_EXPLANATION = "android.app.extra.ADD_EXPLANATION";
@@ -6372,8 +6373,8 @@
     method public long getTxPackets();
     method public int getUid();
     field public static final int ROAMING_ALL = -1; // 0xffffffff
-    field public static final int ROAMING_DEFAULT = 1; // 0x1
-    field public static final int ROAMING_ROAMING = 2; // 0x2
+    field public static final int ROAMING_NO = 1; // 0x1
+    field public static final int ROAMING_YES = 2; // 0x2
     field public static final int STATE_ALL = -1; // 0xffffffff
     field public static final int STATE_DEFAULT = 1; // 0x1
     field public static final int STATE_FOREGROUND = 2; // 0x2
@@ -8113,7 +8114,7 @@
     field public static final java.lang.String DOWNLOAD_SERVICE = "download";
     field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
     field public static final java.lang.String FINGERPRINT_SERVICE = "fingerprint";
-    field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardwareproperties";
+    field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
     field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
@@ -9453,6 +9454,7 @@
     method public int getShortcutIconResId(android.content.pm.ShortcutInfo, android.os.UserHandle);
     method public java.util.List<android.content.pm.ShortcutInfo> getShortcutInfo(java.lang.String, java.util.List<java.lang.String>, android.os.UserHandle);
     method public java.util.List<android.content.pm.ShortcutInfo> getShortcuts(android.content.pm.LauncherApps.ShortcutQuery, android.os.UserHandle);
+    method public boolean hasShortcutHostPermission();
     method public boolean isActivityEnabled(android.content.ComponentName, android.os.UserHandle);
     method public boolean isPackageEnabled(java.lang.String, android.os.UserHandle);
     method public void pinShortcuts(java.lang.String, java.util.List<java.lang.String>, android.os.UserHandle);
@@ -10115,7 +10117,6 @@
     method public static deprecated android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public int describeContents();
-    method public int getChangingConfigurations();
     method public int getColorForState(int[], int);
     method public int getDefaultColor();
     method public boolean isOpaque();
@@ -10127,6 +10128,7 @@
 
   public abstract class ComplexColor {
     ctor public ComplexColor();
+    method public int getChangingConfigurations();
     method public abstract int getDefaultColor();
     method public boolean isStateful();
   }
@@ -13034,9 +13036,9 @@
     method public void setPaddingMode(int);
     method public void setPaddingRelative(int, int, int, int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
+    field public static final int INSET_UNDEFINED = -2147483648; // 0x80000000
     field public static final int PADDING_MODE_NEST = 0; // 0x0
     field public static final int PADDING_MODE_STACK = 1; // 0x1
-    field public static final int UNDEFINED_INSET = -2147483648; // 0x80000000
   }
 
   public class LevelListDrawable extends android.graphics.drawable.DrawableContainer {
@@ -30761,6 +30763,7 @@
   public static class CallLog.Calls implements android.provider.BaseColumns {
     ctor public CallLog.Calls();
     method public static java.lang.String getLastOutgoingCall(android.content.Context);
+    field public static final int ANSWERED_EXTERNALLY_TYPE = 7; // 0x7
     field public static final int BLOCKED_TYPE = 6; // 0x6
     field public static final java.lang.String CACHED_FORMATTED_NUMBER = "formatted_number";
     field public static final java.lang.String CACHED_LOOKUP_URI = "lookup_uri";
@@ -30783,6 +30786,7 @@
     field public static final java.lang.String DURATION = "duration";
     field public static final java.lang.String EXTRA_CALL_TYPE_FILTER = "android.provider.extra.CALL_TYPE_FILTER";
     field public static final java.lang.String FEATURES = "features";
+    field public static final int FEATURES_PULLED_EXTERNALLY = 2; // 0x2
     field public static final int FEATURES_VIDEO = 1; // 0x1
     field public static final java.lang.String GEOCODED_LOCATION = "geocoded_location";
     field public static final int INCOMING_TYPE = 1; // 0x1
@@ -36057,9 +36061,11 @@
     method public void phoneAccountSelected(android.telecom.PhoneAccountHandle, boolean);
     method public void playDtmfTone(char);
     method public void postDialContinue(boolean);
+    method public void pullExternalCall();
     method public void registerCallback(android.telecom.Call.Callback);
     method public void registerCallback(android.telecom.Call.Callback, android.os.Handler);
     method public void reject(boolean, java.lang.String);
+    method public void sendCallEvent(java.lang.String, android.os.Bundle);
     method public void splitFromConference();
     method public void stopDtmfTone();
     method public void swapConference();
@@ -36073,6 +36079,7 @@
     field public static final int STATE_DISCONNECTING = 10; // 0xa
     field public static final int STATE_HOLDING = 3; // 0x3
     field public static final int STATE_NEW = 0; // 0x0
+    field public static final int STATE_PULLING_CALL = 11; // 0xb
     field public static final int STATE_RINGING = 2; // 0x2
     field public static final int STATE_SELECT_PHONE_ACCOUNT = 8; // 0x8
   }
@@ -36083,6 +36090,7 @@
     method public void onCannedTextResponsesLoaded(android.telecom.Call, java.util.List<java.lang.String>);
     method public void onChildrenChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
     method public void onConferenceableCallsChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
+    method public void onConnectionEvent(android.telecom.Call, java.lang.String, android.os.Bundle);
     method public void onDetailsChanged(android.telecom.Call, android.telecom.Call.Details);
     method public void onParentChanged(android.telecom.Call, android.telecom.Call);
     method public void onPostDialWait(android.telecom.Call, java.lang.String);
@@ -36113,6 +36121,7 @@
     method public static java.lang.String propertiesToString(int);
     field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 4194304; // 0x400000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
+    field public static final int CAPABILITY_CAN_PULL_CALL = 8388608; // 0x800000
     field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
     field public static final int CAPABILITY_HOLD = 1; // 0x1
     field public static final int CAPABILITY_MANAGE_CONFERENCE = 128; // 0x80
@@ -36132,6 +36141,7 @@
     field public static final int PROPERTY_EMERGENCY_CALLBACK_MODE = 4; // 0x4
     field public static final int PROPERTY_GENERIC_CONFERENCE = 2; // 0x2
     field public static final int PROPERTY_HIGH_DEF_AUDIO = 16; // 0x10
+    field public static final int PROPERTY_IS_EXTERNAL_CALL = 64; // 0x40
     field public static final int PROPERTY_WIFI = 8; // 0x8
     field public static final int PROPERTY_WORK_CALL = 32; // 0x20
   }
@@ -36246,15 +36256,19 @@
     method public void onAnswer(int);
     method public void onAnswer();
     method public void onCallAudioStateChanged(android.telecom.CallAudioState);
+    method public void onCallEvent(java.lang.String, android.os.Bundle);
     method public void onDisconnect();
     method public void onHold();
     method public void onPlayDtmfTone(char);
     method public void onPostDialContinue(boolean);
+    method public void onPullExternalCall();
     method public void onReject();
+    method public void onReject(java.lang.String);
     method public void onSeparate();
     method public void onStateChanged(int);
     method public void onStopDtmfTone();
     method public void onUnhold();
+    method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
     method public final void setActive();
     method public final void setAddress(android.net.Uri, int);
     method public final void setAudioModeIsVoip(boolean);
@@ -36278,9 +36292,12 @@
     method public static java.lang.String stateToString(int);
     field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 8388608; // 0x800000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
+    field public static final int CAPABILITY_CAN_PULL_CALL = 33554432; // 0x2000000
+    field public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000
     field public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000
     field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
     field public static final int CAPABILITY_HOLD = 1; // 0x1
+    field public static final int CAPABILITY_IS_EXTERNAL_CALL = 16777216; // 0x1000000
     field public static final int CAPABILITY_MANAGE_CONFERENCE = 128; // 0x80
     field public static final int CAPABILITY_MERGE_CONFERENCE = 4; // 0x4
     field public static final int CAPABILITY_MUTE = 64; // 0x40
@@ -36294,6 +36311,7 @@
     field public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 2048; // 0x800
     field public static final int CAPABILITY_SUPPORT_HOLD = 2; // 0x2
     field public static final int CAPABILITY_SWAP_CONFERENCE = 8; // 0x8
+    field public static final java.lang.String EVENT_CALL_PULL_FAILED = "android.telecom.event.CALL_PULL_FAILED";
     field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
     field public static final java.lang.String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
     field public static final java.lang.String EXTRA_LAST_FORWARDED_NUMBER = "android.telecom.extra.LAST_FORWARDED_NUMBER";
@@ -36303,6 +36321,7 @@
     field public static final int STATE_HOLDING = 5; // 0x5
     field public static final int STATE_INITIALIZING = 0; // 0x0
     field public static final int STATE_NEW = 1; // 0x1
+    field public static final int STATE_PULLING_CALL = 7; // 0x7
     field public static final int STATE_RINGING = 2; // 0x2
   }
 
@@ -36380,7 +36399,9 @@
     method public java.lang.String getReason();
     method public int getTone();
     method public void writeToParcel(android.os.Parcel, int);
+    field public static final int ANSWERED_ELSEWHERE = 11; // 0xb
     field public static final int BUSY = 7; // 0x7
+    field public static final int CALL_PULLED = 12; // 0xc
     field public static final int CANCELED = 4; // 0x4
     field public static final int CONNECTION_MANAGER_NOT_SUPPORTED = 10; // 0xa
     field public static final android.os.Parcelable.Creator<android.telecom.DisconnectCause> CREATOR;
@@ -36416,6 +36437,7 @@
     method public void onCallAudioStateChanged(android.telecom.CallAudioState);
     method public void onCallRemoved(android.telecom.Call);
     method public void onCanAddCallChanged(boolean);
+    method public void onConnectionEvent(android.telecom.Call, java.lang.String, android.os.Bundle);
     method public void onSilenceRinger();
     method public final void setAudioRoute(int);
     method public final void setMuted(boolean);
@@ -36566,6 +36588,7 @@
     method public boolean isVoipAudioMode();
     method public void playDtmfTone(char);
     method public void postDialContinue(boolean);
+    method public void pullExternalCall();
     method public void registerCallback(android.telecom.RemoteConnection.Callback);
     method public void registerCallback(android.telecom.RemoteConnection.Callback, android.os.Handler);
     method public void reject();
@@ -36582,6 +36605,7 @@
     method public void onConferenceChanged(android.telecom.RemoteConnection, android.telecom.RemoteConference);
     method public void onConferenceableConnectionsChanged(android.telecom.RemoteConnection, java.util.List<android.telecom.RemoteConnection>);
     method public void onConnectionCapabilitiesChanged(android.telecom.RemoteConnection, int);
+    method public void onConnectionEvent(android.telecom.RemoteConnection, java.lang.String, android.os.Bundle);
     method public void onDestroyed(android.telecom.RemoteConnection);
     method public void onDisconnected(android.telecom.RemoteConnection, android.telecom.DisconnectCause);
     method public void onExtrasChanged(android.telecom.RemoteConnection, android.os.Bundle);
@@ -36679,6 +36703,7 @@
     field public static final java.lang.String EXTRA_START_CALL_WITH_VIDEO_STATE = "android.telecom.extra.START_CALL_WITH_VIDEO_STATE";
     field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS";
     field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
+    field public static final java.lang.String METADATA_INCLUDE_EXTERNAL_CALLS = "android.telecom.INCLUDE_EXTERNAL_CALLS";
     field public static final java.lang.String METADATA_IN_CALL_SERVICE_RINGING = "android.telecom.IN_CALL_SERVICE_RINGING";
     field public static final java.lang.String METADATA_IN_CALL_SERVICE_UI = "android.telecom.IN_CALL_SERVICE_UI";
     field public static final int PRESENTATION_ALLOWED = 1; // 0x1
@@ -42584,6 +42609,7 @@
     method public void onStartTemporaryDetach();
     method public boolean onTouchEvent(android.view.MotionEvent);
     method public boolean onTrackballEvent(android.view.MotionEvent);
+    method public void onVisibilityAggregated(android.view.View, int);
     method protected void onVisibilityChanged(android.view.View, int);
     method public void onWindowFocusChanged(boolean);
     method public void onWindowSystemUiVisibilityChanged(int);
@@ -57343,6 +57369,7 @@
     method public void ensureCapacity(int);
     method public void forEach(java.util.function.Consumer<? super E>);
     method public E get(int);
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
     method public int size();
     method public java.util.Spliterator<E> spliterator();
     method public void trimToSize();
@@ -57427,6 +57454,24 @@
     method public static int hashCode(float[]);
     method public static int hashCode(double[]);
     method public static int hashCode(java.lang.Object[]);
+    method public static void parallelSort(byte[]);
+    method public static void parallelSort(byte[], int, int);
+    method public static void parallelSort(char[]);
+    method public static void parallelSort(char[], int, int);
+    method public static void parallelSort(short[]);
+    method public static void parallelSort(short[], int, int);
+    method public static void parallelSort(int[]);
+    method public static void parallelSort(int[], int, int);
+    method public static void parallelSort(long[]);
+    method public static void parallelSort(long[], int, int);
+    method public static void parallelSort(float[]);
+    method public static void parallelSort(float[], int, int);
+    method public static void parallelSort(double[]);
+    method public static void parallelSort(double[], int, int);
+    method public static void parallelSort(T[]);
+    method public static void parallelSort(T[], int, int);
+    method public static void parallelSort(T[], java.util.Comparator<? super T>);
+    method public static void parallelSort(T[], int, int, java.util.Comparator<? super T>);
     method public static void sort(int[]);
     method public static void sort(int[], int, int);
     method public static void sort(long[]);
@@ -57614,6 +57659,7 @@
     method public abstract java.util.Iterator<E> iterator();
     method public abstract boolean remove(java.lang.Object);
     method public abstract boolean removeAll(java.util.Collection<?>);
+    method public default boolean removeIf(java.util.function.Predicate<? super E>);
     method public abstract boolean retainAll(java.util.Collection<?>);
     method public abstract int size();
     method public abstract java.lang.Object[] toArray();
@@ -58247,18 +58293,28 @@
 
   public abstract interface Map {
     method public abstract void clear();
+    method public default V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public default V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public default V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public abstract boolean containsKey(java.lang.Object);
     method public abstract boolean containsValue(java.lang.Object);
     method public abstract java.util.Set<java.util.Map.Entry<K, V>> entrySet();
     method public abstract boolean equals(java.lang.Object);
     method public default void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public abstract V get(java.lang.Object);
+    method public default V getOrDefault(java.lang.Object, V);
     method public abstract int hashCode();
     method public abstract boolean isEmpty();
     method public abstract java.util.Set<K> keySet();
+    method public default V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public abstract V put(K, V);
     method public abstract void putAll(java.util.Map<? extends K, ? extends V>);
+    method public default V putIfAbsent(K, V);
     method public abstract V remove(java.lang.Object);
+    method public default boolean remove(java.lang.Object, java.lang.Object);
+    method public default boolean replace(K, V, V);
+    method public default V replace(K, V);
+    method public default void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public abstract int size();
     method public abstract java.util.Collection<V> values();
   }
@@ -58266,6 +58322,8 @@
   public static abstract interface Map.Entry {
     method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByKey();
     method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByKey(java.util.Comparator<? super K>);
+    method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByValue();
+    method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByValue(java.util.Comparator<? super V>);
     method public abstract boolean equals(java.lang.Object);
     method public abstract K getKey();
     method public abstract V getValue();
@@ -58996,6 +59054,7 @@
     method public synchronized void removeAllElements();
     method public synchronized boolean removeElement(java.lang.Object);
     method public synchronized void removeElementAt(int);
+    method public synchronized boolean removeIf(java.util.function.Predicate<? super E>);
     method public synchronized void setElementAt(E, int);
     method public synchronized void setSize(int);
     method public synchronized int size();
@@ -59047,6 +59106,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -59110,6 +59170,78 @@
     ctor public CancellationException(java.lang.String);
   }
 
+  public class CompletableFuture implements java.util.concurrent.CompletionStage java.util.concurrent.Future {
+    ctor public CompletableFuture();
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
+    method public static java.util.concurrent.CompletableFuture<java.lang.Void> allOf(java.util.concurrent.CompletableFuture<?>...);
+    method public static java.util.concurrent.CompletableFuture<java.lang.Object> anyOf(java.util.concurrent.CompletableFuture<?>...);
+    method public java.util.concurrent.CompletableFuture<U> applyToEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>);
+    method public java.util.concurrent.CompletableFuture<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>);
+    method public java.util.concurrent.CompletableFuture<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>, java.util.concurrent.Executor);
+    method public boolean cancel(boolean);
+    method public boolean complete(T);
+    method public boolean completeExceptionally(java.lang.Throwable);
+    method public static java.util.concurrent.CompletableFuture<U> completedFuture(U);
+    method public java.util.concurrent.CompletableFuture<T> exceptionally(java.util.function.Function<java.lang.Throwable, ? extends T>);
+    method public T get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
+    method public T get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+    method public T getNow(T);
+    method public int getNumberOfDependents();
+    method public java.util.concurrent.CompletableFuture<U> handle(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>);
+    method public java.util.concurrent.CompletableFuture<U> handleAsync(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>);
+    method public java.util.concurrent.CompletableFuture<U> handleAsync(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>, java.util.concurrent.Executor);
+    method public boolean isCancelled();
+    method public boolean isCompletedExceptionally();
+    method public boolean isDone();
+    method public T join();
+    method public void obtrudeException(java.lang.Throwable);
+    method public void obtrudeValue(T);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBoth(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEither(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable, java.util.concurrent.Executor);
+    method public static java.util.concurrent.CompletableFuture<java.lang.Void> runAsync(java.lang.Runnable);
+    method public static java.util.concurrent.CompletableFuture<java.lang.Void> runAsync(java.lang.Runnable, java.util.concurrent.Executor);
+    method public static java.util.concurrent.CompletableFuture<U> supplyAsync(java.util.function.Supplier<U>);
+    method public static java.util.concurrent.CompletableFuture<U> supplyAsync(java.util.function.Supplier<U>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAccept(java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBoth(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<U> thenApply(java.util.function.Function<? super T, ? extends U>);
+    method public java.util.concurrent.CompletableFuture<U> thenApplyAsync(java.util.function.Function<? super T, ? extends U>);
+    method public java.util.concurrent.CompletableFuture<U> thenApplyAsync(java.util.function.Function<? super T, ? extends U>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<V> thenCombine(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>);
+    method public java.util.concurrent.CompletableFuture<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>);
+    method public java.util.concurrent.CompletableFuture<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<U> thenCompose(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>);
+    method public java.util.concurrent.CompletableFuture<U> thenComposeAsync(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>);
+    method public java.util.concurrent.CompletableFuture<U> thenComposeAsync(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenRun(java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenRunAsync(java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenRunAsync(java.lang.Runnable, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<T> toCompletableFuture();
+    method public java.util.concurrent.CompletableFuture<T> whenComplete(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>);
+    method public java.util.concurrent.CompletableFuture<T> whenCompleteAsync(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>);
+    method public java.util.concurrent.CompletableFuture<T> whenCompleteAsync(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>, java.util.concurrent.Executor);
+  }
+
+  public static abstract interface CompletableFuture.AsynchronousCompletionTask {
+  }
+
+  public class CompletionException extends java.lang.RuntimeException {
+    ctor protected CompletionException();
+    ctor protected CompletionException(java.lang.String);
+    ctor public CompletionException(java.lang.String, java.lang.Throwable);
+    ctor public CompletionException(java.lang.Throwable);
+  }
+
   public abstract interface CompletionService {
     method public abstract java.util.concurrent.Future<V> poll();
     method public abstract java.util.concurrent.Future<V> poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
@@ -59118,20 +59250,130 @@
     method public abstract java.util.concurrent.Future<V> take() throws java.lang.InterruptedException;
   }
 
+  public abstract interface CompletionStage {
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> acceptEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<U> applyToEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>);
+    method public abstract java.util.concurrent.CompletionStage<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>);
+    method public abstract java.util.concurrent.CompletionStage<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<T> exceptionally(java.util.function.Function<java.lang.Throwable, ? extends T>);
+    method public abstract java.util.concurrent.CompletionStage<U> handle(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>);
+    method public abstract java.util.concurrent.CompletionStage<U> handleAsync(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>);
+    method public abstract java.util.concurrent.CompletionStage<U> handleAsync(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterBoth(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterEither(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAccept(java.util.function.Consumer<? super T>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptBoth(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<U> thenApply(java.util.function.Function<? super T, ? extends U>);
+    method public abstract java.util.concurrent.CompletionStage<U> thenApplyAsync(java.util.function.Function<? super T, ? extends U>);
+    method public abstract java.util.concurrent.CompletionStage<U> thenApplyAsync(java.util.function.Function<? super T, ? extends U>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<V> thenCombine(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>);
+    method public abstract java.util.concurrent.CompletionStage<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>);
+    method public abstract java.util.concurrent.CompletionStage<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<U> thenCompose(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>);
+    method public abstract java.util.concurrent.CompletionStage<U> thenComposeAsync(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>);
+    method public abstract java.util.concurrent.CompletionStage<U> thenComposeAsync(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenRun(java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenRunAsync(java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenRunAsync(java.lang.Runnable, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletableFuture<T> toCompletableFuture();
+    method public abstract java.util.concurrent.CompletionStage<T> whenComplete(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>);
+    method public abstract java.util.concurrent.CompletionStage<T> whenCompleteAsync(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>);
+    method public abstract java.util.concurrent.CompletionStage<T> whenCompleteAsync(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>, java.util.concurrent.Executor);
+  }
+
   public class ConcurrentHashMap extends java.util.AbstractMap implements java.util.concurrent.ConcurrentMap java.io.Serializable {
     ctor public ConcurrentHashMap();
     ctor public ConcurrentHashMap(int);
     ctor public ConcurrentHashMap(java.util.Map<? extends K, ? extends V>);
     ctor public ConcurrentHashMap(int, float);
     ctor public ConcurrentHashMap(int, float, int);
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public boolean contains(java.lang.Object);
     method public java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public void forEach(long, java.util.function.BiConsumer<? super K, ? super V>);
+    method public void forEach(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.Consumer<? super U>);
+    method public void forEachEntry(long, java.util.function.Consumer<? super java.util.Map.Entry<K, V>>);
+    method public void forEachEntry(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>, java.util.function.Consumer<? super U>);
+    method public void forEachKey(long, java.util.function.Consumer<? super K>);
+    method public void forEachKey(long, java.util.function.Function<? super K, ? extends U>, java.util.function.Consumer<? super U>);
+    method public void forEachValue(long, java.util.function.Consumer<? super V>);
+    method public void forEachValue(long, java.util.function.Function<? super V, ? extends U>, java.util.function.Consumer<? super U>);
+    method public V getOrDefault(java.lang.Object, V);
+    method public java.util.concurrent.ConcurrentHashMap.KeySetView<K, V> keySet(V);
     method public java.util.Enumeration<K> keys();
+    method public long mappingCount();
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
+    method public static java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet();
+    method public static java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet(int);
     method public V putIfAbsent(K, V);
+    method public U reduce(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
+    method public java.util.Map.Entry<K, V> reduceEntries(long, java.util.function.BiFunction<java.util.Map.Entry<K, V>, java.util.Map.Entry<K, V>, ? extends java.util.Map.Entry<K, V>>);
+    method public U reduceEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
+    method public double reduceEntriesToDouble(long, java.util.function.ToDoubleFunction<java.util.Map.Entry<K, V>>, double, java.util.function.DoubleBinaryOperator);
+    method public int reduceEntriesToInt(long, java.util.function.ToIntFunction<java.util.Map.Entry<K, V>>, int, java.util.function.IntBinaryOperator);
+    method public long reduceEntriesToLong(long, java.util.function.ToLongFunction<java.util.Map.Entry<K, V>>, long, java.util.function.LongBinaryOperator);
+    method public K reduceKeys(long, java.util.function.BiFunction<? super K, ? super K, ? extends K>);
+    method public U reduceKeys(long, java.util.function.Function<? super K, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
+    method public double reduceKeysToDouble(long, java.util.function.ToDoubleFunction<? super K>, double, java.util.function.DoubleBinaryOperator);
+    method public int reduceKeysToInt(long, java.util.function.ToIntFunction<? super K>, int, java.util.function.IntBinaryOperator);
+    method public long reduceKeysToLong(long, java.util.function.ToLongFunction<? super K>, long, java.util.function.LongBinaryOperator);
+    method public double reduceToDouble(long, java.util.function.ToDoubleBiFunction<? super K, ? super V>, double, java.util.function.DoubleBinaryOperator);
+    method public int reduceToInt(long, java.util.function.ToIntBiFunction<? super K, ? super V>, int, java.util.function.IntBinaryOperator);
+    method public long reduceToLong(long, java.util.function.ToLongBiFunction<? super K, ? super V>, long, java.util.function.LongBinaryOperator);
+    method public V reduceValues(long, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
+    method public U reduceValues(long, java.util.function.Function<? super V, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
+    method public double reduceValuesToDouble(long, java.util.function.ToDoubleFunction<? super V>, double, java.util.function.DoubleBinaryOperator);
+    method public int reduceValuesToInt(long, java.util.function.ToIntFunction<? super V>, int, java.util.function.IntBinaryOperator);
+    method public long reduceValuesToLong(long, java.util.function.ToLongFunction<? super V>, long, java.util.function.LongBinaryOperator);
     method public boolean remove(java.lang.Object, java.lang.Object);
     method public boolean replace(K, V, V);
     method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public U search(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>);
+    method public U searchEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>);
+    method public U searchKeys(long, java.util.function.Function<? super K, ? extends U>);
+    method public U searchValues(long, java.util.function.Function<? super V, ? extends U>);
+  }
+
+   static abstract class ConcurrentHashMap.CollectionView implements java.util.Collection java.io.Serializable {
+    method public final void clear();
+    method public abstract boolean contains(java.lang.Object);
+    method public final boolean containsAll(java.util.Collection<?>);
+    method public java.util.concurrent.ConcurrentHashMap<K, V> getMap();
+    method public final boolean isEmpty();
+    method public abstract java.util.Iterator<E> iterator();
+    method public abstract boolean remove(java.lang.Object);
+    method public final boolean removeAll(java.util.Collection<?>);
+    method public final boolean retainAll(java.util.Collection<?>);
+    method public final int size();
+    method public final java.lang.Object[] toArray();
+    method public final T[] toArray(T[]);
+    method public final java.lang.String toString();
+  }
+
+  public static class ConcurrentHashMap.KeySetView extends java.util.concurrent.ConcurrentHashMap.CollectionView implements java.io.Serializable java.util.Set {
+    method public boolean add(K);
+    method public boolean addAll(java.util.Collection<? extends K>);
+    method public boolean contains(java.lang.Object);
+    method public void forEach(java.util.function.Consumer<? super K>);
+    method public V getMappedValue();
+    method public java.util.Iterator<K> iterator();
+    method public boolean remove(java.lang.Object);
+    method public java.util.Spliterator<K> spliterator();
   }
 
   public class ConcurrentLinkedDeque extends java.util.AbstractCollection implements java.util.Deque java.io.Serializable {
@@ -59161,6 +59403,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ConcurrentLinkedQueue extends java.util.AbstractQueue implements java.util.Queue java.io.Serializable {
@@ -59171,6 +59414,7 @@
     method public E peek();
     method public E poll();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface ConcurrentMap implements java.util.Map {
@@ -59202,6 +59446,9 @@
     method public K ceilingKey(K);
     method public java.util.concurrent.ConcurrentSkipListMap<K, V> clone();
     method public java.util.Comparator<? super K> comparator();
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> descendingKeySet();
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> descendingMap();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
@@ -59209,6 +59456,8 @@
     method public K firstKey();
     method public java.util.Map.Entry<K, V> floorEntry(K);
     method public K floorKey(K);
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public V getOrDefault(java.lang.Object, V);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
@@ -59217,6 +59466,7 @@
     method public K lastKey();
     method public java.util.Map.Entry<K, V> lowerEntry(K);
     method public K lowerKey(K);
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> navigableKeySet();
     method public java.util.Map.Entry<K, V> pollFirstEntry();
     method public java.util.Map.Entry<K, V> pollLastEntry();
@@ -59224,6 +59474,7 @@
     method public boolean remove(java.lang.Object, java.lang.Object);
     method public boolean replace(K, V, V);
     method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, K);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> tailMap(K, boolean);
@@ -59251,6 +59502,7 @@
     method public E pollFirst();
     method public E pollLast();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
     method public java.util.NavigableSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -59261,31 +59513,34 @@
     ctor public CopyOnWriteArrayList();
     ctor public CopyOnWriteArrayList(java.util.Collection<? extends E>);
     ctor public CopyOnWriteArrayList(E[]);
-    method public synchronized boolean add(E);
-    method public synchronized void add(int, E);
-    method public synchronized boolean addAll(java.util.Collection<? extends E>);
-    method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
-    method public synchronized int addAllAbsent(java.util.Collection<? extends E>);
-    method public synchronized boolean addIfAbsent(E);
-    method public synchronized void clear();
+    method public boolean add(E);
+    method public void add(int, E);
+    method public boolean addAll(java.util.Collection<? extends E>);
+    method public boolean addAll(int, java.util.Collection<? extends E>);
+    method public int addAllAbsent(java.util.Collection<? extends E>);
+    method public boolean addIfAbsent(E);
+    method public void clear();
     method public java.lang.Object clone();
     method public boolean contains(java.lang.Object);
     method public boolean containsAll(java.util.Collection<?>);
+    method public void forEach(java.util.function.Consumer<? super E>);
     method public E get(int);
-    method public int indexOf(E, int);
     method public int indexOf(java.lang.Object);
+    method public int indexOf(E, int);
     method public boolean isEmpty();
     method public java.util.Iterator<E> iterator();
-    method public int lastIndexOf(E, int);
     method public int lastIndexOf(java.lang.Object);
-    method public java.util.ListIterator<E> listIterator(int);
+    method public int lastIndexOf(E, int);
     method public java.util.ListIterator<E> listIterator();
-    method public synchronized E remove(int);
-    method public synchronized boolean remove(java.lang.Object);
-    method public synchronized boolean removeAll(java.util.Collection<?>);
-    method public synchronized boolean retainAll(java.util.Collection<?>);
-    method public synchronized E set(int, E);
+    method public java.util.ListIterator<E> listIterator(int);
+    method public E remove(int);
+    method public boolean remove(java.lang.Object);
+    method public boolean removeAll(java.util.Collection<?>);
+    method public void replaceAll(java.util.function.UnaryOperator<E>);
+    method public boolean retainAll(java.util.Collection<?>);
+    method public E set(int, E);
     method public int size();
+    method public void sort(java.util.Comparator<? super E>);
     method public java.util.List<E> subList(int, int);
     method public java.lang.Object[] toArray();
     method public T[] toArray(T[]);
@@ -59294,8 +59549,11 @@
   public class CopyOnWriteArraySet extends java.util.AbstractSet implements java.io.Serializable {
     ctor public CopyOnWriteArraySet();
     ctor public CopyOnWriteArraySet(java.util.Collection<? extends E>);
+    method public void forEach(java.util.function.Consumer<? super E>);
     method public java.util.Iterator<E> iterator();
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class CountDownLatch {
@@ -59306,6 +59564,32 @@
     method public long getCount();
   }
 
+  public abstract class CountedCompleter extends java.util.concurrent.ForkJoinTask {
+    ctor protected CountedCompleter(java.util.concurrent.CountedCompleter<?>, int);
+    ctor protected CountedCompleter(java.util.concurrent.CountedCompleter<?>);
+    ctor protected CountedCompleter();
+    method public final void addToPendingCount(int);
+    method public final boolean compareAndSetPendingCount(int, int);
+    method public void complete(T);
+    method public abstract void compute();
+    method public final int decrementPendingCountUnlessZero();
+    method protected final boolean exec();
+    method public final java.util.concurrent.CountedCompleter<?> firstComplete();
+    method public final java.util.concurrent.CountedCompleter<?> getCompleter();
+    method public final int getPendingCount();
+    method public T getRawResult();
+    method public final java.util.concurrent.CountedCompleter<?> getRoot();
+    method public final void helpComplete(int);
+    method public final java.util.concurrent.CountedCompleter<?> nextComplete();
+    method public void onCompletion(java.util.concurrent.CountedCompleter<?>);
+    method public boolean onExceptionalCompletion(java.lang.Throwable, java.util.concurrent.CountedCompleter<?>);
+    method public final void propagateCompletion();
+    method public final void quietlyCompleteRoot();
+    method public final void setPendingCount(int);
+    method protected void setRawResult(T);
+    method public final void tryComplete();
+  }
+
   public class CyclicBarrier {
     ctor public CyclicBarrier(int, java.lang.Runnable);
     ctor public CyclicBarrier(int);
@@ -59396,6 +59680,8 @@
     method public static java.util.concurrent.ExecutorService newSingleThreadExecutor(java.util.concurrent.ThreadFactory);
     method public static java.util.concurrent.ScheduledExecutorService newSingleThreadScheduledExecutor();
     method public static java.util.concurrent.ScheduledExecutorService newSingleThreadScheduledExecutor(java.util.concurrent.ThreadFactory);
+    method public static java.util.concurrent.ExecutorService newWorkStealingPool(int);
+    method public static java.util.concurrent.ExecutorService newWorkStealingPool();
     method public static java.util.concurrent.Callable<T> privilegedCallable(java.util.concurrent.Callable<T>);
     method public static java.util.concurrent.Callable<T> privilegedCallableUsingCurrentClassLoader(java.util.concurrent.Callable<T>);
     method public static java.util.concurrent.ThreadFactory privilegedThreadFactory();
@@ -59409,11 +59695,13 @@
     ctor public ForkJoinPool(int, java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory, java.lang.Thread.UncaughtExceptionHandler, boolean);
     method public boolean awaitQuiescence(long, java.util.concurrent.TimeUnit);
     method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public static java.util.concurrent.ForkJoinPool commonPool();
     method protected int drainTasksTo(java.util.Collection<? super java.util.concurrent.ForkJoinTask<?>>);
     method public void execute(java.util.concurrent.ForkJoinTask<?>);
     method public void execute(java.lang.Runnable);
     method public int getActiveThreadCount();
     method public boolean getAsyncMode();
+    method public static int getCommonPoolParallelism();
     method public java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory getFactory();
     method public int getParallelism();
     method public int getPoolSize();
@@ -59451,6 +59739,7 @@
     method public static java.util.concurrent.ForkJoinTask<T> adapt(java.lang.Runnable, T);
     method public static java.util.concurrent.ForkJoinTask<T> adapt(java.util.concurrent.Callable<? extends T>);
     method public boolean cancel(boolean);
+    method public final boolean compareAndSetForkJoinTaskTag(short, short);
     method public void complete(V);
     method public void completeExceptionally(java.lang.Throwable);
     method protected abstract boolean exec();
@@ -59458,6 +59747,7 @@
     method public final V get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
     method public final V get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
     method public final java.lang.Throwable getException();
+    method public final short getForkJoinTaskTag();
     method public static java.util.concurrent.ForkJoinPool getPool();
     method public static int getQueuedTaskCount();
     method public abstract V getRawResult();
@@ -59476,9 +59766,11 @@
     method protected static java.util.concurrent.ForkJoinTask<?> peekNextLocalTask();
     method protected static java.util.concurrent.ForkJoinTask<?> pollNextLocalTask();
     method protected static java.util.concurrent.ForkJoinTask<?> pollTask();
+    method public final void quietlyComplete();
     method public final void quietlyInvoke();
     method public final void quietlyJoin();
     method public void reinitialize();
+    method public final short setForkJoinTaskTag(short);
     method protected abstract void setRawResult(V);
     method public boolean tryUnfork();
   }
@@ -59552,6 +59844,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public E takeFirst() throws java.lang.InterruptedException;
     method public E takeLast() throws java.lang.InterruptedException;
@@ -59572,6 +59865,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -59591,6 +59885,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public void transfer(E) throws java.lang.InterruptedException;
     method public boolean tryTransfer(E);
@@ -59638,6 +59933,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -59741,6 +60037,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -59870,112 +60167,136 @@
   public class AtomicInteger extends java.lang.Number implements java.io.Serializable {
     ctor public AtomicInteger(int);
     ctor public AtomicInteger();
+    method public final int accumulateAndGet(int, java.util.function.IntBinaryOperator);
     method public final int addAndGet(int);
     method public final boolean compareAndSet(int, int);
     method public final int decrementAndGet();
     method public double doubleValue();
     method public float floatValue();
     method public final int get();
+    method public final int getAndAccumulate(int, java.util.function.IntBinaryOperator);
     method public final int getAndAdd(int);
     method public final int getAndDecrement();
     method public final int getAndIncrement();
     method public final int getAndSet(int);
+    method public final int getAndUpdate(java.util.function.IntUnaryOperator);
     method public final int incrementAndGet();
     method public int intValue();
     method public final void lazySet(int);
     method public long longValue();
     method public final void set(int);
+    method public final int updateAndGet(java.util.function.IntUnaryOperator);
     method public final boolean weakCompareAndSet(int, int);
   }
 
   public class AtomicIntegerArray implements java.io.Serializable {
     ctor public AtomicIntegerArray(int);
     ctor public AtomicIntegerArray(int[]);
+    method public final int accumulateAndGet(int, int, java.util.function.IntBinaryOperator);
     method public final int addAndGet(int, int);
     method public final boolean compareAndSet(int, int, int);
     method public final int decrementAndGet(int);
     method public final int get(int);
+    method public final int getAndAccumulate(int, int, java.util.function.IntBinaryOperator);
     method public final int getAndAdd(int, int);
     method public final int getAndDecrement(int);
     method public final int getAndIncrement(int);
     method public final int getAndSet(int, int);
+    method public final int getAndUpdate(int, java.util.function.IntUnaryOperator);
     method public final int incrementAndGet(int);
     method public final void lazySet(int, int);
     method public final int length();
     method public final void set(int, int);
+    method public final int updateAndGet(int, java.util.function.IntUnaryOperator);
     method public final boolean weakCompareAndSet(int, int, int);
   }
 
   public abstract class AtomicIntegerFieldUpdater {
     ctor protected AtomicIntegerFieldUpdater();
+    method public final int accumulateAndGet(T, int, java.util.function.IntBinaryOperator);
     method public int addAndGet(T, int);
     method public abstract boolean compareAndSet(T, int, int);
     method public int decrementAndGet(T);
     method public abstract int get(T);
+    method public final int getAndAccumulate(T, int, java.util.function.IntBinaryOperator);
     method public int getAndAdd(T, int);
     method public int getAndDecrement(T);
     method public int getAndIncrement(T);
     method public int getAndSet(T, int);
+    method public final int getAndUpdate(T, java.util.function.IntUnaryOperator);
     method public int incrementAndGet(T);
     method public abstract void lazySet(T, int);
     method public static java.util.concurrent.atomic.AtomicIntegerFieldUpdater<U> newUpdater(java.lang.Class<U>, java.lang.String);
     method public abstract void set(T, int);
+    method public final int updateAndGet(T, java.util.function.IntUnaryOperator);
     method public abstract boolean weakCompareAndSet(T, int, int);
   }
 
   public class AtomicLong extends java.lang.Number implements java.io.Serializable {
     ctor public AtomicLong(long);
     ctor public AtomicLong();
+    method public final long accumulateAndGet(long, java.util.function.LongBinaryOperator);
     method public final long addAndGet(long);
     method public final boolean compareAndSet(long, long);
     method public final long decrementAndGet();
     method public double doubleValue();
     method public float floatValue();
     method public final long get();
+    method public final long getAndAccumulate(long, java.util.function.LongBinaryOperator);
     method public final long getAndAdd(long);
     method public final long getAndDecrement();
     method public final long getAndIncrement();
     method public final long getAndSet(long);
+    method public final long getAndUpdate(java.util.function.LongUnaryOperator);
     method public final long incrementAndGet();
     method public int intValue();
     method public final void lazySet(long);
     method public long longValue();
     method public final void set(long);
+    method public final long updateAndGet(java.util.function.LongUnaryOperator);
     method public final boolean weakCompareAndSet(long, long);
   }
 
   public class AtomicLongArray implements java.io.Serializable {
     ctor public AtomicLongArray(int);
     ctor public AtomicLongArray(long[]);
+    method public final long accumulateAndGet(int, long, java.util.function.LongBinaryOperator);
     method public long addAndGet(int, long);
     method public final boolean compareAndSet(int, long, long);
     method public final long decrementAndGet(int);
     method public final long get(int);
+    method public final long getAndAccumulate(int, long, java.util.function.LongBinaryOperator);
     method public final long getAndAdd(int, long);
     method public final long getAndDecrement(int);
     method public final long getAndIncrement(int);
     method public final long getAndSet(int, long);
+    method public final long getAndUpdate(int, java.util.function.LongUnaryOperator);
     method public final long incrementAndGet(int);
     method public final void lazySet(int, long);
     method public final int length();
     method public final void set(int, long);
+    method public final long updateAndGet(int, java.util.function.LongUnaryOperator);
     method public final boolean weakCompareAndSet(int, long, long);
   }
 
   public abstract class AtomicLongFieldUpdater {
     ctor protected AtomicLongFieldUpdater();
+    method public final long accumulateAndGet(T, long, java.util.function.LongBinaryOperator);
     method public long addAndGet(T, long);
     method public abstract boolean compareAndSet(T, long, long);
     method public long decrementAndGet(T);
     method public abstract long get(T);
+    method public final long getAndAccumulate(T, long, java.util.function.LongBinaryOperator);
     method public long getAndAdd(T, long);
     method public long getAndDecrement(T);
     method public long getAndIncrement(T);
     method public long getAndSet(T, long);
+    method public final long getAndUpdate(T, java.util.function.LongUnaryOperator);
     method public long incrementAndGet(T);
     method public abstract void lazySet(T, long);
     method public static java.util.concurrent.atomic.AtomicLongFieldUpdater<U> newUpdater(java.lang.Class<U>, java.lang.String);
     method public abstract void set(T, long);
+    method public final long updateAndGet(T, java.util.function.LongUnaryOperator);
     method public abstract boolean weakCompareAndSet(T, long, long);
   }
 
@@ -59993,34 +60314,46 @@
   public class AtomicReference implements java.io.Serializable {
     ctor public AtomicReference(V);
     ctor public AtomicReference();
+    method public final V accumulateAndGet(V, java.util.function.BinaryOperator<V>);
     method public final boolean compareAndSet(V, V);
     method public final V get();
+    method public final V getAndAccumulate(V, java.util.function.BinaryOperator<V>);
     method public final V getAndSet(V);
+    method public final V getAndUpdate(java.util.function.UnaryOperator<V>);
     method public final void lazySet(V);
     method public final void set(V);
+    method public final V updateAndGet(java.util.function.UnaryOperator<V>);
     method public final boolean weakCompareAndSet(V, V);
   }
 
   public class AtomicReferenceArray implements java.io.Serializable {
     ctor public AtomicReferenceArray(int);
     ctor public AtomicReferenceArray(E[]);
+    method public final E accumulateAndGet(int, E, java.util.function.BinaryOperator<E>);
     method public final boolean compareAndSet(int, E, E);
     method public final E get(int);
+    method public final E getAndAccumulate(int, E, java.util.function.BinaryOperator<E>);
     method public final E getAndSet(int, E);
+    method public final E getAndUpdate(int, java.util.function.UnaryOperator<E>);
     method public final void lazySet(int, E);
     method public final int length();
     method public final void set(int, E);
+    method public final E updateAndGet(int, java.util.function.UnaryOperator<E>);
     method public final boolean weakCompareAndSet(int, E, E);
   }
 
   public abstract class AtomicReferenceFieldUpdater {
     ctor protected AtomicReferenceFieldUpdater();
+    method public final V accumulateAndGet(T, V, java.util.function.BinaryOperator<V>);
     method public abstract boolean compareAndSet(T, V, V);
     method public abstract V get(T);
+    method public final V getAndAccumulate(T, V, java.util.function.BinaryOperator<V>);
     method public V getAndSet(T, V);
+    method public final V getAndUpdate(T, java.util.function.UnaryOperator<V>);
     method public abstract void lazySet(T, V);
     method public static java.util.concurrent.atomic.AtomicReferenceFieldUpdater<U, W> newUpdater(java.lang.Class<U>, java.lang.Class<W>, java.lang.String);
     method public abstract void set(T, V);
+    method public final V updateAndGet(T, java.util.function.UnaryOperator<V>);
     method public abstract boolean weakCompareAndSet(T, V, V);
   }
 
@@ -60035,6 +60368,59 @@
     method public boolean weakCompareAndSet(V, V, int, int);
   }
 
+  public class DoubleAccumulator extends java.util.concurrent.atomic.Striped64 implements java.io.Serializable {
+    ctor public DoubleAccumulator(java.util.function.DoubleBinaryOperator, double);
+    method public void accumulate(double);
+    method public double doubleValue();
+    method public float floatValue();
+    method public double get();
+    method public double getThenReset();
+    method public int intValue();
+    method public long longValue();
+    method public void reset();
+  }
+
+  public class DoubleAdder extends java.util.concurrent.atomic.Striped64 implements java.io.Serializable {
+    ctor public DoubleAdder();
+    method public void add(double);
+    method public double doubleValue();
+    method public float floatValue();
+    method public int intValue();
+    method public long longValue();
+    method public void reset();
+    method public double sum();
+    method public double sumThenReset();
+  }
+
+  public class LongAccumulator extends java.util.concurrent.atomic.Striped64 implements java.io.Serializable {
+    ctor public LongAccumulator(java.util.function.LongBinaryOperator, long);
+    method public void accumulate(long);
+    method public double doubleValue();
+    method public float floatValue();
+    method public long get();
+    method public long getThenReset();
+    method public int intValue();
+    method public long longValue();
+    method public void reset();
+  }
+
+  public class LongAdder extends java.util.concurrent.atomic.Striped64 implements java.io.Serializable {
+    ctor public LongAdder();
+    method public void add(long);
+    method public void decrement();
+    method public double doubleValue();
+    method public float floatValue();
+    method public void increment();
+    method public int intValue();
+    method public long longValue();
+    method public void reset();
+    method public long sum();
+    method public long sumThenReset();
+  }
+
+   abstract class Striped64 extends java.lang.Number {
+  }
+
 }
 
 package java.util.concurrent.locks {
@@ -60242,6 +60628,34 @@
     method public void unlock();
   }
 
+  public class StampedLock implements java.io.Serializable {
+    ctor public StampedLock();
+    method public java.util.concurrent.locks.Lock asReadLock();
+    method public java.util.concurrent.locks.ReadWriteLock asReadWriteLock();
+    method public java.util.concurrent.locks.Lock asWriteLock();
+    method public int getReadLockCount();
+    method public boolean isReadLocked();
+    method public boolean isWriteLocked();
+    method public long readLock();
+    method public long readLockInterruptibly() throws java.lang.InterruptedException;
+    method public long tryConvertToOptimisticRead(long);
+    method public long tryConvertToReadLock(long);
+    method public long tryConvertToWriteLock(long);
+    method public long tryOptimisticRead();
+    method public long tryReadLock();
+    method public long tryReadLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public boolean tryUnlockRead();
+    method public boolean tryUnlockWrite();
+    method public long tryWriteLock();
+    method public long tryWriteLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public void unlock(long);
+    method public void unlockRead(long);
+    method public void unlockWrite(long);
+    method public boolean validate(long);
+    method public long writeLock();
+    method public long writeLockInterruptibly() throws java.lang.InterruptedException;
+  }
+
 }
 
 package java.util.function {
diff --git a/api/system-current.txt b/api/system-current.txt
index 0743b91..d2d7e17 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3557,7 +3557,7 @@
     method public android.view.View getCurrentFocus();
     method public android.app.FragmentManager getFragmentManager();
     method public android.content.Intent getIntent();
-    method public deprecated java.lang.Object getLastNonConfigurationInstance();
+    method public java.lang.Object getLastNonConfigurationInstance();
     method public android.view.LayoutInflater getLayoutInflater();
     method public android.app.LoaderManager getLoaderManager();
     method public java.lang.String getLocalClassName();
@@ -3660,7 +3660,7 @@
     method protected void onRestoreInstanceState(android.os.Bundle);
     method public void onRestoreInstanceState(android.os.Bundle, android.os.PersistableBundle);
     method protected void onResume();
-    method public deprecated java.lang.Object onRetainNonConfigurationInstance();
+    method public java.lang.Object onRetainNonConfigurationInstance();
     method protected void onSaveInstanceState(android.os.Bundle);
     method public void onSaveInstanceState(android.os.Bundle, android.os.PersistableBundle);
     method public boolean onSearchRequested(android.view.SearchEvent);
@@ -6130,6 +6130,7 @@
     field public static final int ENCRYPTION_STATUS_ACTIVATING = 2; // 0x2
     field public static final int ENCRYPTION_STATUS_ACTIVE = 3; // 0x3
     field public static final int ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY = 4; // 0x4
+    field public static final int ENCRYPTION_STATUS_ACTIVE_PER_USER = 5; // 0x5
     field public static final int ENCRYPTION_STATUS_INACTIVE = 1; // 0x1
     field public static final int ENCRYPTION_STATUS_UNSUPPORTED = 0; // 0x0
     field public static final java.lang.String EXTRA_ADD_EXPLANATION = "android.app.extra.ADD_EXPLANATION";
@@ -6638,8 +6639,8 @@
     method public long getTxPackets();
     method public int getUid();
     field public static final int ROAMING_ALL = -1; // 0xffffffff
-    field public static final int ROAMING_DEFAULT = 1; // 0x1
-    field public static final int ROAMING_ROAMING = 2; // 0x2
+    field public static final int ROAMING_NO = 1; // 0x1
+    field public static final int ROAMING_YES = 2; // 0x2
     field public static final int STATE_ALL = -1; // 0xffffffff
     field public static final int STATE_DEFAULT = 1; // 0x1
     field public static final int STATE_FOREGROUND = 2; // 0x2
@@ -8416,7 +8417,7 @@
     field public static final java.lang.String DOWNLOAD_SERVICE = "download";
     field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
     field public static final java.lang.String FINGERPRINT_SERVICE = "fingerprint";
-    field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardwareproperties";
+    field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
     field public static final java.lang.String HDMI_CONTROL_SERVICE = "hdmi_control";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
@@ -9787,6 +9788,7 @@
     method public int getShortcutIconResId(android.content.pm.ShortcutInfo, android.os.UserHandle);
     method public java.util.List<android.content.pm.ShortcutInfo> getShortcutInfo(java.lang.String, java.util.List<java.lang.String>, android.os.UserHandle);
     method public java.util.List<android.content.pm.ShortcutInfo> getShortcuts(android.content.pm.LauncherApps.ShortcutQuery, android.os.UserHandle);
+    method public boolean hasShortcutHostPermission();
     method public boolean isActivityEnabled(android.content.ComponentName, android.os.UserHandle);
     method public boolean isPackageEnabled(java.lang.String, android.os.UserHandle);
     method public void pinShortcuts(java.lang.String, java.util.List<java.lang.String>, android.os.UserHandle);
@@ -9927,11 +9929,11 @@
   public static class PackageInstaller.SessionParams implements android.os.Parcelable {
     ctor public PackageInstaller.SessionParams(int);
     method public int describeContents();
+    method public void setAllowDowngrade(boolean);
     method public void setAppIcon(android.graphics.Bitmap);
     method public void setAppLabel(java.lang.CharSequence);
     method public void setAppPackageName(java.lang.String);
     method public void setGrantedRuntimePermissions(java.lang.String[]);
-    method public void setInstallFlagsDowngrade();
     method public void setInstallLocation(int);
     method public void setOriginatingUid(int);
     method public void setOriginatingUri(android.net.Uri);
@@ -10510,7 +10512,6 @@
     method public static deprecated android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public int describeContents();
-    method public int getChangingConfigurations();
     method public int getColorForState(int[], int);
     method public int getDefaultColor();
     method public boolean isOpaque();
@@ -10522,6 +10523,7 @@
 
   public abstract class ComplexColor {
     ctor public ComplexColor();
+    method public int getChangingConfigurations();
     method public abstract int getDefaultColor();
     method public boolean isStateful();
   }
@@ -13429,9 +13431,9 @@
     method public void setPaddingMode(int);
     method public void setPaddingRelative(int, int, int, int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
+    field public static final int INSET_UNDEFINED = -2147483648; // 0x80000000
     field public static final int PADDING_MODE_NEST = 0; // 0x0
     field public static final int PADDING_MODE_STACK = 1; // 0x1
-    field public static final int UNDEFINED_INSET = -2147483648; // 0x80000000
   }
 
   public class LevelListDrawable extends android.graphics.drawable.DrawableContainer {
@@ -33113,6 +33115,7 @@
   public static class CallLog.Calls implements android.provider.BaseColumns {
     ctor public CallLog.Calls();
     method public static java.lang.String getLastOutgoingCall(android.content.Context);
+    field public static final int ANSWERED_EXTERNALLY_TYPE = 7; // 0x7
     field public static final int BLOCKED_TYPE = 6; // 0x6
     field public static final java.lang.String CACHED_FORMATTED_NUMBER = "formatted_number";
     field public static final java.lang.String CACHED_LOOKUP_URI = "lookup_uri";
@@ -33135,6 +33138,7 @@
     field public static final java.lang.String DURATION = "duration";
     field public static final java.lang.String EXTRA_CALL_TYPE_FILTER = "android.provider.extra.CALL_TYPE_FILTER";
     field public static final java.lang.String FEATURES = "features";
+    field public static final int FEATURES_PULLED_EXTERNALLY = 2; // 0x2
     field public static final int FEATURES_VIDEO = 1; // 0x1
     field public static final java.lang.String GEOCODED_LOCATION = "geocoded_location";
     field public static final int INCOMING_TYPE = 1; // 0x1
@@ -38657,10 +38661,12 @@
     method public void phoneAccountSelected(android.telecom.PhoneAccountHandle, boolean);
     method public void playDtmfTone(char);
     method public void postDialContinue(boolean);
+    method public void pullExternalCall();
     method public void registerCallback(android.telecom.Call.Callback);
     method public void registerCallback(android.telecom.Call.Callback, android.os.Handler);
     method public void reject(boolean, java.lang.String);
     method public deprecated void removeListener(android.telecom.Call.Listener);
+    method public void sendCallEvent(java.lang.String, android.os.Bundle);
     method public void splitFromConference();
     method public void stopDtmfTone();
     method public void swapConference();
@@ -38675,6 +38681,7 @@
     field public static final int STATE_HOLDING = 3; // 0x3
     field public static final int STATE_NEW = 0; // 0x0
     field public static final deprecated int STATE_PRE_DIAL_WAIT = 8; // 0x8
+    field public static final int STATE_PULLING_CALL = 11; // 0xb
     field public static final int STATE_RINGING = 2; // 0x2
     field public static final int STATE_SELECT_PHONE_ACCOUNT = 8; // 0x8
   }
@@ -38685,6 +38692,7 @@
     method public void onCannedTextResponsesLoaded(android.telecom.Call, java.util.List<java.lang.String>);
     method public void onChildrenChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
     method public void onConferenceableCallsChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
+    method public void onConnectionEvent(android.telecom.Call, java.lang.String, android.os.Bundle);
     method public void onDetailsChanged(android.telecom.Call, android.telecom.Call.Details);
     method public void onParentChanged(android.telecom.Call, android.telecom.Call);
     method public void onPostDialWait(android.telecom.Call, java.lang.String);
@@ -38715,6 +38723,7 @@
     method public static java.lang.String propertiesToString(int);
     field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 4194304; // 0x400000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
+    field public static final int CAPABILITY_CAN_PULL_CALL = 8388608; // 0x800000
     field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
     field public static final int CAPABILITY_HOLD = 1; // 0x1
     field public static final int CAPABILITY_MANAGE_CONFERENCE = 128; // 0x80
@@ -38734,6 +38743,7 @@
     field public static final int PROPERTY_EMERGENCY_CALLBACK_MODE = 4; // 0x4
     field public static final int PROPERTY_GENERIC_CONFERENCE = 2; // 0x2
     field public static final int PROPERTY_HIGH_DEF_AUDIO = 16; // 0x10
+    field public static final int PROPERTY_IS_EXTERNAL_CALL = 64; // 0x40
     field public static final int PROPERTY_WIFI = 8; // 0x8
     field public static final int PROPERTY_WORK_CALL = 32; // 0x20
   }
@@ -38859,15 +38869,19 @@
     method public void onAnswer();
     method public deprecated void onAudioStateChanged(android.telecom.AudioState);
     method public void onCallAudioStateChanged(android.telecom.CallAudioState);
+    method public void onCallEvent(java.lang.String, android.os.Bundle);
     method public void onDisconnect();
     method public void onHold();
     method public void onPlayDtmfTone(char);
     method public void onPostDialContinue(boolean);
+    method public void onPullExternalCall();
     method public void onReject();
+    method public void onReject(java.lang.String);
     method public void onSeparate();
     method public void onStateChanged(int);
     method public void onStopDtmfTone();
     method public void onUnhold();
+    method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
     method public final void setActive();
     method public final void setAddress(android.net.Uri, int);
     method public final void setAudioModeIsVoip(boolean);
@@ -38891,9 +38905,12 @@
     method public static java.lang.String stateToString(int);
     field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 8388608; // 0x800000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
+    field public static final int CAPABILITY_CAN_PULL_CALL = 33554432; // 0x2000000
+    field public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000
     field public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000
     field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
     field public static final int CAPABILITY_HOLD = 1; // 0x1
+    field public static final int CAPABILITY_IS_EXTERNAL_CALL = 16777216; // 0x1000000
     field public static final int CAPABILITY_MANAGE_CONFERENCE = 128; // 0x80
     field public static final int CAPABILITY_MERGE_CONFERENCE = 4; // 0x4
     field public static final int CAPABILITY_MUTE = 64; // 0x40
@@ -38907,6 +38924,7 @@
     field public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 2048; // 0x800
     field public static final int CAPABILITY_SUPPORT_HOLD = 2; // 0x2
     field public static final int CAPABILITY_SWAP_CONFERENCE = 8; // 0x8
+    field public static final java.lang.String EVENT_CALL_PULL_FAILED = "android.telecom.event.CALL_PULL_FAILED";
     field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
     field public static final java.lang.String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
     field public static final java.lang.String EXTRA_LAST_FORWARDED_NUMBER = "android.telecom.extra.LAST_FORWARDED_NUMBER";
@@ -38916,6 +38934,7 @@
     field public static final int STATE_HOLDING = 5; // 0x5
     field public static final int STATE_INITIALIZING = 0; // 0x0
     field public static final int STATE_NEW = 1; // 0x1
+    field public static final int STATE_PULLING_CALL = 7; // 0x7
     field public static final int STATE_RINGING = 2; // 0x2
   }
 
@@ -38993,7 +39012,9 @@
     method public java.lang.String getReason();
     method public int getTone();
     method public void writeToParcel(android.os.Parcel, int);
+    field public static final int ANSWERED_ELSEWHERE = 11; // 0xb
     field public static final int BUSY = 7; // 0x7
+    field public static final int CALL_PULLED = 12; // 0xc
     field public static final int CANCELED = 4; // 0x4
     field public static final int CONNECTION_MANAGER_NOT_SUPPORTED = 10; // 0xa
     field public static final android.os.Parcelable.Creator<android.telecom.DisconnectCause> CREATOR;
@@ -39030,6 +39051,7 @@
     method public void onCallAudioStateChanged(android.telecom.CallAudioState);
     method public void onCallRemoved(android.telecom.Call);
     method public void onCanAddCallChanged(boolean);
+    method public void onConnectionEvent(android.telecom.Call, java.lang.String, android.os.Bundle);
     method public deprecated void onPhoneCreated(android.telecom.Phone);
     method public deprecated void onPhoneDestroyed(android.telecom.Phone);
     method public void onSilenceRinger();
@@ -39235,6 +39257,7 @@
     method public boolean isVoipAudioMode();
     method public void playDtmfTone(char);
     method public void postDialContinue(boolean);
+    method public void pullExternalCall();
     method public void registerCallback(android.telecom.RemoteConnection.Callback);
     method public void registerCallback(android.telecom.RemoteConnection.Callback, android.os.Handler);
     method public void reject();
@@ -39252,6 +39275,7 @@
     method public void onConferenceChanged(android.telecom.RemoteConnection, android.telecom.RemoteConference);
     method public void onConferenceableConnectionsChanged(android.telecom.RemoteConnection, java.util.List<android.telecom.RemoteConnection>);
     method public void onConnectionCapabilitiesChanged(android.telecom.RemoteConnection, int);
+    method public void onConnectionEvent(android.telecom.RemoteConnection, java.lang.String, android.os.Bundle);
     method public void onDestroyed(android.telecom.RemoteConnection);
     method public void onDisconnected(android.telecom.RemoteConnection, android.telecom.DisconnectCause);
     method public void onExtrasChanged(android.telecom.RemoteConnection, android.os.Bundle);
@@ -39376,6 +39400,7 @@
     field public static final java.lang.String EXTRA_START_CALL_WITH_VIDEO_STATE = "android.telecom.extra.START_CALL_WITH_VIDEO_STATE";
     field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS";
     field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
+    field public static final java.lang.String METADATA_INCLUDE_EXTERNAL_CALLS = "android.telecom.INCLUDE_EXTERNAL_CALLS";
     field public static final java.lang.String METADATA_IN_CALL_SERVICE_RINGING = "android.telecom.IN_CALL_SERVICE_RINGING";
     field public static final java.lang.String METADATA_IN_CALL_SERVICE_UI = "android.telecom.IN_CALL_SERVICE_UI";
     field public static final int PRESENTATION_ALLOWED = 1; // 0x1
@@ -45347,6 +45372,7 @@
     method public void onStartTemporaryDetach();
     method public boolean onTouchEvent(android.view.MotionEvent);
     method public boolean onTrackballEvent(android.view.MotionEvent);
+    method public void onVisibilityAggregated(android.view.View, int);
     method protected void onVisibilityChanged(android.view.View, int);
     method public void onWindowFocusChanged(boolean);
     method public void onWindowSystemUiVisibilityChanged(int);
@@ -60443,6 +60469,7 @@
     method public void ensureCapacity(int);
     method public void forEach(java.util.function.Consumer<? super E>);
     method public E get(int);
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
     method public int size();
     method public java.util.Spliterator<E> spliterator();
     method public void trimToSize();
@@ -60527,6 +60554,24 @@
     method public static int hashCode(float[]);
     method public static int hashCode(double[]);
     method public static int hashCode(java.lang.Object[]);
+    method public static void parallelSort(byte[]);
+    method public static void parallelSort(byte[], int, int);
+    method public static void parallelSort(char[]);
+    method public static void parallelSort(char[], int, int);
+    method public static void parallelSort(short[]);
+    method public static void parallelSort(short[], int, int);
+    method public static void parallelSort(int[]);
+    method public static void parallelSort(int[], int, int);
+    method public static void parallelSort(long[]);
+    method public static void parallelSort(long[], int, int);
+    method public static void parallelSort(float[]);
+    method public static void parallelSort(float[], int, int);
+    method public static void parallelSort(double[]);
+    method public static void parallelSort(double[], int, int);
+    method public static void parallelSort(T[]);
+    method public static void parallelSort(T[], int, int);
+    method public static void parallelSort(T[], java.util.Comparator<? super T>);
+    method public static void parallelSort(T[], int, int, java.util.Comparator<? super T>);
     method public static void sort(int[]);
     method public static void sort(int[], int, int);
     method public static void sort(long[]);
@@ -60714,6 +60759,7 @@
     method public abstract java.util.Iterator<E> iterator();
     method public abstract boolean remove(java.lang.Object);
     method public abstract boolean removeAll(java.util.Collection<?>);
+    method public default boolean removeIf(java.util.function.Predicate<? super E>);
     method public abstract boolean retainAll(java.util.Collection<?>);
     method public abstract int size();
     method public abstract java.lang.Object[] toArray();
@@ -61347,18 +61393,28 @@
 
   public abstract interface Map {
     method public abstract void clear();
+    method public default V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public default V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public default V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public abstract boolean containsKey(java.lang.Object);
     method public abstract boolean containsValue(java.lang.Object);
     method public abstract java.util.Set<java.util.Map.Entry<K, V>> entrySet();
     method public abstract boolean equals(java.lang.Object);
     method public default void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public abstract V get(java.lang.Object);
+    method public default V getOrDefault(java.lang.Object, V);
     method public abstract int hashCode();
     method public abstract boolean isEmpty();
     method public abstract java.util.Set<K> keySet();
+    method public default V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public abstract V put(K, V);
     method public abstract void putAll(java.util.Map<? extends K, ? extends V>);
+    method public default V putIfAbsent(K, V);
     method public abstract V remove(java.lang.Object);
+    method public default boolean remove(java.lang.Object, java.lang.Object);
+    method public default boolean replace(K, V, V);
+    method public default V replace(K, V);
+    method public default void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public abstract int size();
     method public abstract java.util.Collection<V> values();
   }
@@ -61366,6 +61422,8 @@
   public static abstract interface Map.Entry {
     method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByKey();
     method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByKey(java.util.Comparator<? super K>);
+    method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByValue();
+    method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByValue(java.util.Comparator<? super V>);
     method public abstract boolean equals(java.lang.Object);
     method public abstract K getKey();
     method public abstract V getValue();
@@ -62096,6 +62154,7 @@
     method public synchronized void removeAllElements();
     method public synchronized boolean removeElement(java.lang.Object);
     method public synchronized void removeElementAt(int);
+    method public synchronized boolean removeIf(java.util.function.Predicate<? super E>);
     method public synchronized void setElementAt(E, int);
     method public synchronized void setSize(int);
     method public synchronized int size();
@@ -62147,6 +62206,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -62210,6 +62270,78 @@
     ctor public CancellationException(java.lang.String);
   }
 
+  public class CompletableFuture implements java.util.concurrent.CompletionStage java.util.concurrent.Future {
+    ctor public CompletableFuture();
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
+    method public static java.util.concurrent.CompletableFuture<java.lang.Void> allOf(java.util.concurrent.CompletableFuture<?>...);
+    method public static java.util.concurrent.CompletableFuture<java.lang.Object> anyOf(java.util.concurrent.CompletableFuture<?>...);
+    method public java.util.concurrent.CompletableFuture<U> applyToEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>);
+    method public java.util.concurrent.CompletableFuture<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>);
+    method public java.util.concurrent.CompletableFuture<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>, java.util.concurrent.Executor);
+    method public boolean cancel(boolean);
+    method public boolean complete(T);
+    method public boolean completeExceptionally(java.lang.Throwable);
+    method public static java.util.concurrent.CompletableFuture<U> completedFuture(U);
+    method public java.util.concurrent.CompletableFuture<T> exceptionally(java.util.function.Function<java.lang.Throwable, ? extends T>);
+    method public T get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
+    method public T get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+    method public T getNow(T);
+    method public int getNumberOfDependents();
+    method public java.util.concurrent.CompletableFuture<U> handle(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>);
+    method public java.util.concurrent.CompletableFuture<U> handleAsync(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>);
+    method public java.util.concurrent.CompletableFuture<U> handleAsync(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>, java.util.concurrent.Executor);
+    method public boolean isCancelled();
+    method public boolean isCompletedExceptionally();
+    method public boolean isDone();
+    method public T join();
+    method public void obtrudeException(java.lang.Throwable);
+    method public void obtrudeValue(T);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBoth(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEither(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable, java.util.concurrent.Executor);
+    method public static java.util.concurrent.CompletableFuture<java.lang.Void> runAsync(java.lang.Runnable);
+    method public static java.util.concurrent.CompletableFuture<java.lang.Void> runAsync(java.lang.Runnable, java.util.concurrent.Executor);
+    method public static java.util.concurrent.CompletableFuture<U> supplyAsync(java.util.function.Supplier<U>);
+    method public static java.util.concurrent.CompletableFuture<U> supplyAsync(java.util.function.Supplier<U>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAccept(java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBoth(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<U> thenApply(java.util.function.Function<? super T, ? extends U>);
+    method public java.util.concurrent.CompletableFuture<U> thenApplyAsync(java.util.function.Function<? super T, ? extends U>);
+    method public java.util.concurrent.CompletableFuture<U> thenApplyAsync(java.util.function.Function<? super T, ? extends U>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<V> thenCombine(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>);
+    method public java.util.concurrent.CompletableFuture<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>);
+    method public java.util.concurrent.CompletableFuture<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<U> thenCompose(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>);
+    method public java.util.concurrent.CompletableFuture<U> thenComposeAsync(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>);
+    method public java.util.concurrent.CompletableFuture<U> thenComposeAsync(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenRun(java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenRunAsync(java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenRunAsync(java.lang.Runnable, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<T> toCompletableFuture();
+    method public java.util.concurrent.CompletableFuture<T> whenComplete(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>);
+    method public java.util.concurrent.CompletableFuture<T> whenCompleteAsync(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>);
+    method public java.util.concurrent.CompletableFuture<T> whenCompleteAsync(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>, java.util.concurrent.Executor);
+  }
+
+  public static abstract interface CompletableFuture.AsynchronousCompletionTask {
+  }
+
+  public class CompletionException extends java.lang.RuntimeException {
+    ctor protected CompletionException();
+    ctor protected CompletionException(java.lang.String);
+    ctor public CompletionException(java.lang.String, java.lang.Throwable);
+    ctor public CompletionException(java.lang.Throwable);
+  }
+
   public abstract interface CompletionService {
     method public abstract java.util.concurrent.Future<V> poll();
     method public abstract java.util.concurrent.Future<V> poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
@@ -62218,20 +62350,130 @@
     method public abstract java.util.concurrent.Future<V> take() throws java.lang.InterruptedException;
   }
 
+  public abstract interface CompletionStage {
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> acceptEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<U> applyToEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>);
+    method public abstract java.util.concurrent.CompletionStage<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>);
+    method public abstract java.util.concurrent.CompletionStage<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<T> exceptionally(java.util.function.Function<java.lang.Throwable, ? extends T>);
+    method public abstract java.util.concurrent.CompletionStage<U> handle(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>);
+    method public abstract java.util.concurrent.CompletionStage<U> handleAsync(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>);
+    method public abstract java.util.concurrent.CompletionStage<U> handleAsync(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterBoth(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterEither(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAccept(java.util.function.Consumer<? super T>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptBoth(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<U> thenApply(java.util.function.Function<? super T, ? extends U>);
+    method public abstract java.util.concurrent.CompletionStage<U> thenApplyAsync(java.util.function.Function<? super T, ? extends U>);
+    method public abstract java.util.concurrent.CompletionStage<U> thenApplyAsync(java.util.function.Function<? super T, ? extends U>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<V> thenCombine(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>);
+    method public abstract java.util.concurrent.CompletionStage<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>);
+    method public abstract java.util.concurrent.CompletionStage<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<U> thenCompose(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>);
+    method public abstract java.util.concurrent.CompletionStage<U> thenComposeAsync(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>);
+    method public abstract java.util.concurrent.CompletionStage<U> thenComposeAsync(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenRun(java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenRunAsync(java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenRunAsync(java.lang.Runnable, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletableFuture<T> toCompletableFuture();
+    method public abstract java.util.concurrent.CompletionStage<T> whenComplete(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>);
+    method public abstract java.util.concurrent.CompletionStage<T> whenCompleteAsync(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>);
+    method public abstract java.util.concurrent.CompletionStage<T> whenCompleteAsync(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>, java.util.concurrent.Executor);
+  }
+
   public class ConcurrentHashMap extends java.util.AbstractMap implements java.util.concurrent.ConcurrentMap java.io.Serializable {
     ctor public ConcurrentHashMap();
     ctor public ConcurrentHashMap(int);
     ctor public ConcurrentHashMap(java.util.Map<? extends K, ? extends V>);
     ctor public ConcurrentHashMap(int, float);
     ctor public ConcurrentHashMap(int, float, int);
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public boolean contains(java.lang.Object);
     method public java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public void forEach(long, java.util.function.BiConsumer<? super K, ? super V>);
+    method public void forEach(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.Consumer<? super U>);
+    method public void forEachEntry(long, java.util.function.Consumer<? super java.util.Map.Entry<K, V>>);
+    method public void forEachEntry(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>, java.util.function.Consumer<? super U>);
+    method public void forEachKey(long, java.util.function.Consumer<? super K>);
+    method public void forEachKey(long, java.util.function.Function<? super K, ? extends U>, java.util.function.Consumer<? super U>);
+    method public void forEachValue(long, java.util.function.Consumer<? super V>);
+    method public void forEachValue(long, java.util.function.Function<? super V, ? extends U>, java.util.function.Consumer<? super U>);
+    method public V getOrDefault(java.lang.Object, V);
+    method public java.util.concurrent.ConcurrentHashMap.KeySetView<K, V> keySet(V);
     method public java.util.Enumeration<K> keys();
+    method public long mappingCount();
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
+    method public static java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet();
+    method public static java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet(int);
     method public V putIfAbsent(K, V);
+    method public U reduce(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
+    method public java.util.Map.Entry<K, V> reduceEntries(long, java.util.function.BiFunction<java.util.Map.Entry<K, V>, java.util.Map.Entry<K, V>, ? extends java.util.Map.Entry<K, V>>);
+    method public U reduceEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
+    method public double reduceEntriesToDouble(long, java.util.function.ToDoubleFunction<java.util.Map.Entry<K, V>>, double, java.util.function.DoubleBinaryOperator);
+    method public int reduceEntriesToInt(long, java.util.function.ToIntFunction<java.util.Map.Entry<K, V>>, int, java.util.function.IntBinaryOperator);
+    method public long reduceEntriesToLong(long, java.util.function.ToLongFunction<java.util.Map.Entry<K, V>>, long, java.util.function.LongBinaryOperator);
+    method public K reduceKeys(long, java.util.function.BiFunction<? super K, ? super K, ? extends K>);
+    method public U reduceKeys(long, java.util.function.Function<? super K, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
+    method public double reduceKeysToDouble(long, java.util.function.ToDoubleFunction<? super K>, double, java.util.function.DoubleBinaryOperator);
+    method public int reduceKeysToInt(long, java.util.function.ToIntFunction<? super K>, int, java.util.function.IntBinaryOperator);
+    method public long reduceKeysToLong(long, java.util.function.ToLongFunction<? super K>, long, java.util.function.LongBinaryOperator);
+    method public double reduceToDouble(long, java.util.function.ToDoubleBiFunction<? super K, ? super V>, double, java.util.function.DoubleBinaryOperator);
+    method public int reduceToInt(long, java.util.function.ToIntBiFunction<? super K, ? super V>, int, java.util.function.IntBinaryOperator);
+    method public long reduceToLong(long, java.util.function.ToLongBiFunction<? super K, ? super V>, long, java.util.function.LongBinaryOperator);
+    method public V reduceValues(long, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
+    method public U reduceValues(long, java.util.function.Function<? super V, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
+    method public double reduceValuesToDouble(long, java.util.function.ToDoubleFunction<? super V>, double, java.util.function.DoubleBinaryOperator);
+    method public int reduceValuesToInt(long, java.util.function.ToIntFunction<? super V>, int, java.util.function.IntBinaryOperator);
+    method public long reduceValuesToLong(long, java.util.function.ToLongFunction<? super V>, long, java.util.function.LongBinaryOperator);
     method public boolean remove(java.lang.Object, java.lang.Object);
     method public boolean replace(K, V, V);
     method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public U search(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>);
+    method public U searchEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>);
+    method public U searchKeys(long, java.util.function.Function<? super K, ? extends U>);
+    method public U searchValues(long, java.util.function.Function<? super V, ? extends U>);
+  }
+
+   static abstract class ConcurrentHashMap.CollectionView implements java.util.Collection java.io.Serializable {
+    method public final void clear();
+    method public abstract boolean contains(java.lang.Object);
+    method public final boolean containsAll(java.util.Collection<?>);
+    method public java.util.concurrent.ConcurrentHashMap<K, V> getMap();
+    method public final boolean isEmpty();
+    method public abstract java.util.Iterator<E> iterator();
+    method public abstract boolean remove(java.lang.Object);
+    method public final boolean removeAll(java.util.Collection<?>);
+    method public final boolean retainAll(java.util.Collection<?>);
+    method public final int size();
+    method public final java.lang.Object[] toArray();
+    method public final T[] toArray(T[]);
+    method public final java.lang.String toString();
+  }
+
+  public static class ConcurrentHashMap.KeySetView extends java.util.concurrent.ConcurrentHashMap.CollectionView implements java.io.Serializable java.util.Set {
+    method public boolean add(K);
+    method public boolean addAll(java.util.Collection<? extends K>);
+    method public boolean contains(java.lang.Object);
+    method public void forEach(java.util.function.Consumer<? super K>);
+    method public V getMappedValue();
+    method public java.util.Iterator<K> iterator();
+    method public boolean remove(java.lang.Object);
+    method public java.util.Spliterator<K> spliterator();
   }
 
   public class ConcurrentLinkedDeque extends java.util.AbstractCollection implements java.util.Deque java.io.Serializable {
@@ -62261,6 +62503,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ConcurrentLinkedQueue extends java.util.AbstractQueue implements java.util.Queue java.io.Serializable {
@@ -62271,6 +62514,7 @@
     method public E peek();
     method public E poll();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface ConcurrentMap implements java.util.Map {
@@ -62302,6 +62546,9 @@
     method public K ceilingKey(K);
     method public java.util.concurrent.ConcurrentSkipListMap<K, V> clone();
     method public java.util.Comparator<? super K> comparator();
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> descendingKeySet();
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> descendingMap();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
@@ -62309,6 +62556,8 @@
     method public K firstKey();
     method public java.util.Map.Entry<K, V> floorEntry(K);
     method public K floorKey(K);
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public V getOrDefault(java.lang.Object, V);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
@@ -62317,6 +62566,7 @@
     method public K lastKey();
     method public java.util.Map.Entry<K, V> lowerEntry(K);
     method public K lowerKey(K);
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> navigableKeySet();
     method public java.util.Map.Entry<K, V> pollFirstEntry();
     method public java.util.Map.Entry<K, V> pollLastEntry();
@@ -62324,6 +62574,7 @@
     method public boolean remove(java.lang.Object, java.lang.Object);
     method public boolean replace(K, V, V);
     method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, K);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> tailMap(K, boolean);
@@ -62351,6 +62602,7 @@
     method public E pollFirst();
     method public E pollLast();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
     method public java.util.NavigableSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -62361,31 +62613,34 @@
     ctor public CopyOnWriteArrayList();
     ctor public CopyOnWriteArrayList(java.util.Collection<? extends E>);
     ctor public CopyOnWriteArrayList(E[]);
-    method public synchronized boolean add(E);
-    method public synchronized void add(int, E);
-    method public synchronized boolean addAll(java.util.Collection<? extends E>);
-    method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
-    method public synchronized int addAllAbsent(java.util.Collection<? extends E>);
-    method public synchronized boolean addIfAbsent(E);
-    method public synchronized void clear();
+    method public boolean add(E);
+    method public void add(int, E);
+    method public boolean addAll(java.util.Collection<? extends E>);
+    method public boolean addAll(int, java.util.Collection<? extends E>);
+    method public int addAllAbsent(java.util.Collection<? extends E>);
+    method public boolean addIfAbsent(E);
+    method public void clear();
     method public java.lang.Object clone();
     method public boolean contains(java.lang.Object);
     method public boolean containsAll(java.util.Collection<?>);
+    method public void forEach(java.util.function.Consumer<? super E>);
     method public E get(int);
-    method public int indexOf(E, int);
     method public int indexOf(java.lang.Object);
+    method public int indexOf(E, int);
     method public boolean isEmpty();
     method public java.util.Iterator<E> iterator();
-    method public int lastIndexOf(E, int);
     method public int lastIndexOf(java.lang.Object);
-    method public java.util.ListIterator<E> listIterator(int);
+    method public int lastIndexOf(E, int);
     method public java.util.ListIterator<E> listIterator();
-    method public synchronized E remove(int);
-    method public synchronized boolean remove(java.lang.Object);
-    method public synchronized boolean removeAll(java.util.Collection<?>);
-    method public synchronized boolean retainAll(java.util.Collection<?>);
-    method public synchronized E set(int, E);
+    method public java.util.ListIterator<E> listIterator(int);
+    method public E remove(int);
+    method public boolean remove(java.lang.Object);
+    method public boolean removeAll(java.util.Collection<?>);
+    method public void replaceAll(java.util.function.UnaryOperator<E>);
+    method public boolean retainAll(java.util.Collection<?>);
+    method public E set(int, E);
     method public int size();
+    method public void sort(java.util.Comparator<? super E>);
     method public java.util.List<E> subList(int, int);
     method public java.lang.Object[] toArray();
     method public T[] toArray(T[]);
@@ -62394,8 +62649,11 @@
   public class CopyOnWriteArraySet extends java.util.AbstractSet implements java.io.Serializable {
     ctor public CopyOnWriteArraySet();
     ctor public CopyOnWriteArraySet(java.util.Collection<? extends E>);
+    method public void forEach(java.util.function.Consumer<? super E>);
     method public java.util.Iterator<E> iterator();
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class CountDownLatch {
@@ -62406,6 +62664,32 @@
     method public long getCount();
   }
 
+  public abstract class CountedCompleter extends java.util.concurrent.ForkJoinTask {
+    ctor protected CountedCompleter(java.util.concurrent.CountedCompleter<?>, int);
+    ctor protected CountedCompleter(java.util.concurrent.CountedCompleter<?>);
+    ctor protected CountedCompleter();
+    method public final void addToPendingCount(int);
+    method public final boolean compareAndSetPendingCount(int, int);
+    method public void complete(T);
+    method public abstract void compute();
+    method public final int decrementPendingCountUnlessZero();
+    method protected final boolean exec();
+    method public final java.util.concurrent.CountedCompleter<?> firstComplete();
+    method public final java.util.concurrent.CountedCompleter<?> getCompleter();
+    method public final int getPendingCount();
+    method public T getRawResult();
+    method public final java.util.concurrent.CountedCompleter<?> getRoot();
+    method public final void helpComplete(int);
+    method public final java.util.concurrent.CountedCompleter<?> nextComplete();
+    method public void onCompletion(java.util.concurrent.CountedCompleter<?>);
+    method public boolean onExceptionalCompletion(java.lang.Throwable, java.util.concurrent.CountedCompleter<?>);
+    method public final void propagateCompletion();
+    method public final void quietlyCompleteRoot();
+    method public final void setPendingCount(int);
+    method protected void setRawResult(T);
+    method public final void tryComplete();
+  }
+
   public class CyclicBarrier {
     ctor public CyclicBarrier(int, java.lang.Runnable);
     ctor public CyclicBarrier(int);
@@ -62496,6 +62780,8 @@
     method public static java.util.concurrent.ExecutorService newSingleThreadExecutor(java.util.concurrent.ThreadFactory);
     method public static java.util.concurrent.ScheduledExecutorService newSingleThreadScheduledExecutor();
     method public static java.util.concurrent.ScheduledExecutorService newSingleThreadScheduledExecutor(java.util.concurrent.ThreadFactory);
+    method public static java.util.concurrent.ExecutorService newWorkStealingPool(int);
+    method public static java.util.concurrent.ExecutorService newWorkStealingPool();
     method public static java.util.concurrent.Callable<T> privilegedCallable(java.util.concurrent.Callable<T>);
     method public static java.util.concurrent.Callable<T> privilegedCallableUsingCurrentClassLoader(java.util.concurrent.Callable<T>);
     method public static java.util.concurrent.ThreadFactory privilegedThreadFactory();
@@ -62509,11 +62795,13 @@
     ctor public ForkJoinPool(int, java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory, java.lang.Thread.UncaughtExceptionHandler, boolean);
     method public boolean awaitQuiescence(long, java.util.concurrent.TimeUnit);
     method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public static java.util.concurrent.ForkJoinPool commonPool();
     method protected int drainTasksTo(java.util.Collection<? super java.util.concurrent.ForkJoinTask<?>>);
     method public void execute(java.util.concurrent.ForkJoinTask<?>);
     method public void execute(java.lang.Runnable);
     method public int getActiveThreadCount();
     method public boolean getAsyncMode();
+    method public static int getCommonPoolParallelism();
     method public java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory getFactory();
     method public int getParallelism();
     method public int getPoolSize();
@@ -62551,6 +62839,7 @@
     method public static java.util.concurrent.ForkJoinTask<T> adapt(java.lang.Runnable, T);
     method public static java.util.concurrent.ForkJoinTask<T> adapt(java.util.concurrent.Callable<? extends T>);
     method public boolean cancel(boolean);
+    method public final boolean compareAndSetForkJoinTaskTag(short, short);
     method public void complete(V);
     method public void completeExceptionally(java.lang.Throwable);
     method protected abstract boolean exec();
@@ -62558,6 +62847,7 @@
     method public final V get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
     method public final V get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
     method public final java.lang.Throwable getException();
+    method public final short getForkJoinTaskTag();
     method public static java.util.concurrent.ForkJoinPool getPool();
     method public static int getQueuedTaskCount();
     method public abstract V getRawResult();
@@ -62576,9 +62866,11 @@
     method protected static java.util.concurrent.ForkJoinTask<?> peekNextLocalTask();
     method protected static java.util.concurrent.ForkJoinTask<?> pollNextLocalTask();
     method protected static java.util.concurrent.ForkJoinTask<?> pollTask();
+    method public final void quietlyComplete();
     method public final void quietlyInvoke();
     method public final void quietlyJoin();
     method public void reinitialize();
+    method public final short setForkJoinTaskTag(short);
     method protected abstract void setRawResult(V);
     method public boolean tryUnfork();
   }
@@ -62652,6 +62944,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public E takeFirst() throws java.lang.InterruptedException;
     method public E takeLast() throws java.lang.InterruptedException;
@@ -62672,6 +62965,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -62691,6 +62985,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public void transfer(E) throws java.lang.InterruptedException;
     method public boolean tryTransfer(E);
@@ -62738,6 +63033,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -62841,6 +63137,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -62970,112 +63267,136 @@
   public class AtomicInteger extends java.lang.Number implements java.io.Serializable {
     ctor public AtomicInteger(int);
     ctor public AtomicInteger();
+    method public final int accumulateAndGet(int, java.util.function.IntBinaryOperator);
     method public final int addAndGet(int);
     method public final boolean compareAndSet(int, int);
     method public final int decrementAndGet();
     method public double doubleValue();
     method public float floatValue();
     method public final int get();
+    method public final int getAndAccumulate(int, java.util.function.IntBinaryOperator);
     method public final int getAndAdd(int);
     method public final int getAndDecrement();
     method public final int getAndIncrement();
     method public final int getAndSet(int);
+    method public final int getAndUpdate(java.util.function.IntUnaryOperator);
     method public final int incrementAndGet();
     method public int intValue();
     method public final void lazySet(int);
     method public long longValue();
     method public final void set(int);
+    method public final int updateAndGet(java.util.function.IntUnaryOperator);
     method public final boolean weakCompareAndSet(int, int);
   }
 
   public class AtomicIntegerArray implements java.io.Serializable {
     ctor public AtomicIntegerArray(int);
     ctor public AtomicIntegerArray(int[]);
+    method public final int accumulateAndGet(int, int, java.util.function.IntBinaryOperator);
     method public final int addAndGet(int, int);
     method public final boolean compareAndSet(int, int, int);
     method public final int decrementAndGet(int);
     method public final int get(int);
+    method public final int getAndAccumulate(int, int, java.util.function.IntBinaryOperator);
     method public final int getAndAdd(int, int);
     method public final int getAndDecrement(int);
     method public final int getAndIncrement(int);
     method public final int getAndSet(int, int);
+    method public final int getAndUpdate(int, java.util.function.IntUnaryOperator);
     method public final int incrementAndGet(int);
     method public final void lazySet(int, int);
     method public final int length();
     method public final void set(int, int);
+    method public final int updateAndGet(int, java.util.function.IntUnaryOperator);
     method public final boolean weakCompareAndSet(int, int, int);
   }
 
   public abstract class AtomicIntegerFieldUpdater {
     ctor protected AtomicIntegerFieldUpdater();
+    method public final int accumulateAndGet(T, int, java.util.function.IntBinaryOperator);
     method public int addAndGet(T, int);
     method public abstract boolean compareAndSet(T, int, int);
     method public int decrementAndGet(T);
     method public abstract int get(T);
+    method public final int getAndAccumulate(T, int, java.util.function.IntBinaryOperator);
     method public int getAndAdd(T, int);
     method public int getAndDecrement(T);
     method public int getAndIncrement(T);
     method public int getAndSet(T, int);
+    method public final int getAndUpdate(T, java.util.function.IntUnaryOperator);
     method public int incrementAndGet(T);
     method public abstract void lazySet(T, int);
     method public static java.util.concurrent.atomic.AtomicIntegerFieldUpdater<U> newUpdater(java.lang.Class<U>, java.lang.String);
     method public abstract void set(T, int);
+    method public final int updateAndGet(T, java.util.function.IntUnaryOperator);
     method public abstract boolean weakCompareAndSet(T, int, int);
   }
 
   public class AtomicLong extends java.lang.Number implements java.io.Serializable {
     ctor public AtomicLong(long);
     ctor public AtomicLong();
+    method public final long accumulateAndGet(long, java.util.function.LongBinaryOperator);
     method public final long addAndGet(long);
     method public final boolean compareAndSet(long, long);
     method public final long decrementAndGet();
     method public double doubleValue();
     method public float floatValue();
     method public final long get();
+    method public final long getAndAccumulate(long, java.util.function.LongBinaryOperator);
     method public final long getAndAdd(long);
     method public final long getAndDecrement();
     method public final long getAndIncrement();
     method public final long getAndSet(long);
+    method public final long getAndUpdate(java.util.function.LongUnaryOperator);
     method public final long incrementAndGet();
     method public int intValue();
     method public final void lazySet(long);
     method public long longValue();
     method public final void set(long);
+    method public final long updateAndGet(java.util.function.LongUnaryOperator);
     method public final boolean weakCompareAndSet(long, long);
   }
 
   public class AtomicLongArray implements java.io.Serializable {
     ctor public AtomicLongArray(int);
     ctor public AtomicLongArray(long[]);
+    method public final long accumulateAndGet(int, long, java.util.function.LongBinaryOperator);
     method public long addAndGet(int, long);
     method public final boolean compareAndSet(int, long, long);
     method public final long decrementAndGet(int);
     method public final long get(int);
+    method public final long getAndAccumulate(int, long, java.util.function.LongBinaryOperator);
     method public final long getAndAdd(int, long);
     method public final long getAndDecrement(int);
     method public final long getAndIncrement(int);
     method public final long getAndSet(int, long);
+    method public final long getAndUpdate(int, java.util.function.LongUnaryOperator);
     method public final long incrementAndGet(int);
     method public final void lazySet(int, long);
     method public final int length();
     method public final void set(int, long);
+    method public final long updateAndGet(int, java.util.function.LongUnaryOperator);
     method public final boolean weakCompareAndSet(int, long, long);
   }
 
   public abstract class AtomicLongFieldUpdater {
     ctor protected AtomicLongFieldUpdater();
+    method public final long accumulateAndGet(T, long, java.util.function.LongBinaryOperator);
     method public long addAndGet(T, long);
     method public abstract boolean compareAndSet(T, long, long);
     method public long decrementAndGet(T);
     method public abstract long get(T);
+    method public final long getAndAccumulate(T, long, java.util.function.LongBinaryOperator);
     method public long getAndAdd(T, long);
     method public long getAndDecrement(T);
     method public long getAndIncrement(T);
     method public long getAndSet(T, long);
+    method public final long getAndUpdate(T, java.util.function.LongUnaryOperator);
     method public long incrementAndGet(T);
     method public abstract void lazySet(T, long);
     method public static java.util.concurrent.atomic.AtomicLongFieldUpdater<U> newUpdater(java.lang.Class<U>, java.lang.String);
     method public abstract void set(T, long);
+    method public final long updateAndGet(T, java.util.function.LongUnaryOperator);
     method public abstract boolean weakCompareAndSet(T, long, long);
   }
 
@@ -63093,34 +63414,46 @@
   public class AtomicReference implements java.io.Serializable {
     ctor public AtomicReference(V);
     ctor public AtomicReference();
+    method public final V accumulateAndGet(V, java.util.function.BinaryOperator<V>);
     method public final boolean compareAndSet(V, V);
     method public final V get();
+    method public final V getAndAccumulate(V, java.util.function.BinaryOperator<V>);
     method public final V getAndSet(V);
+    method public final V getAndUpdate(java.util.function.UnaryOperator<V>);
     method public final void lazySet(V);
     method public final void set(V);
+    method public final V updateAndGet(java.util.function.UnaryOperator<V>);
     method public final boolean weakCompareAndSet(V, V);
   }
 
   public class AtomicReferenceArray implements java.io.Serializable {
     ctor public AtomicReferenceArray(int);
     ctor public AtomicReferenceArray(E[]);
+    method public final E accumulateAndGet(int, E, java.util.function.BinaryOperator<E>);
     method public final boolean compareAndSet(int, E, E);
     method public final E get(int);
+    method public final E getAndAccumulate(int, E, java.util.function.BinaryOperator<E>);
     method public final E getAndSet(int, E);
+    method public final E getAndUpdate(int, java.util.function.UnaryOperator<E>);
     method public final void lazySet(int, E);
     method public final int length();
     method public final void set(int, E);
+    method public final E updateAndGet(int, java.util.function.UnaryOperator<E>);
     method public final boolean weakCompareAndSet(int, E, E);
   }
 
   public abstract class AtomicReferenceFieldUpdater {
     ctor protected AtomicReferenceFieldUpdater();
+    method public final V accumulateAndGet(T, V, java.util.function.BinaryOperator<V>);
     method public abstract boolean compareAndSet(T, V, V);
     method public abstract V get(T);
+    method public final V getAndAccumulate(T, V, java.util.function.BinaryOperator<V>);
     method public V getAndSet(T, V);
+    method public final V getAndUpdate(T, java.util.function.UnaryOperator<V>);
     method public abstract void lazySet(T, V);
     method public static java.util.concurrent.atomic.AtomicReferenceFieldUpdater<U, W> newUpdater(java.lang.Class<U>, java.lang.Class<W>, java.lang.String);
     method public abstract void set(T, V);
+    method public final V updateAndGet(T, java.util.function.UnaryOperator<V>);
     method public abstract boolean weakCompareAndSet(T, V, V);
   }
 
@@ -63135,6 +63468,59 @@
     method public boolean weakCompareAndSet(V, V, int, int);
   }
 
+  public class DoubleAccumulator extends java.util.concurrent.atomic.Striped64 implements java.io.Serializable {
+    ctor public DoubleAccumulator(java.util.function.DoubleBinaryOperator, double);
+    method public void accumulate(double);
+    method public double doubleValue();
+    method public float floatValue();
+    method public double get();
+    method public double getThenReset();
+    method public int intValue();
+    method public long longValue();
+    method public void reset();
+  }
+
+  public class DoubleAdder extends java.util.concurrent.atomic.Striped64 implements java.io.Serializable {
+    ctor public DoubleAdder();
+    method public void add(double);
+    method public double doubleValue();
+    method public float floatValue();
+    method public int intValue();
+    method public long longValue();
+    method public void reset();
+    method public double sum();
+    method public double sumThenReset();
+  }
+
+  public class LongAccumulator extends java.util.concurrent.atomic.Striped64 implements java.io.Serializable {
+    ctor public LongAccumulator(java.util.function.LongBinaryOperator, long);
+    method public void accumulate(long);
+    method public double doubleValue();
+    method public float floatValue();
+    method public long get();
+    method public long getThenReset();
+    method public int intValue();
+    method public long longValue();
+    method public void reset();
+  }
+
+  public class LongAdder extends java.util.concurrent.atomic.Striped64 implements java.io.Serializable {
+    ctor public LongAdder();
+    method public void add(long);
+    method public void decrement();
+    method public double doubleValue();
+    method public float floatValue();
+    method public void increment();
+    method public int intValue();
+    method public long longValue();
+    method public void reset();
+    method public long sum();
+    method public long sumThenReset();
+  }
+
+   abstract class Striped64 extends java.lang.Number {
+  }
+
 }
 
 package java.util.concurrent.locks {
@@ -63342,6 +63728,34 @@
     method public void unlock();
   }
 
+  public class StampedLock implements java.io.Serializable {
+    ctor public StampedLock();
+    method public java.util.concurrent.locks.Lock asReadLock();
+    method public java.util.concurrent.locks.ReadWriteLock asReadWriteLock();
+    method public java.util.concurrent.locks.Lock asWriteLock();
+    method public int getReadLockCount();
+    method public boolean isReadLocked();
+    method public boolean isWriteLocked();
+    method public long readLock();
+    method public long readLockInterruptibly() throws java.lang.InterruptedException;
+    method public long tryConvertToOptimisticRead(long);
+    method public long tryConvertToReadLock(long);
+    method public long tryConvertToWriteLock(long);
+    method public long tryOptimisticRead();
+    method public long tryReadLock();
+    method public long tryReadLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public boolean tryUnlockRead();
+    method public boolean tryUnlockWrite();
+    method public long tryWriteLock();
+    method public long tryWriteLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public void unlock(long);
+    method public void unlockRead(long);
+    method public void unlockWrite(long);
+    method public boolean validate(long);
+    method public long writeLock();
+    method public long writeLockInterruptibly() throws java.lang.InterruptedException;
+  }
+
 }
 
 package java.util.function {
diff --git a/api/test-current.txt b/api/test-current.txt
index a7b434c..eeef74a 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3442,7 +3442,7 @@
     method public android.view.View getCurrentFocus();
     method public android.app.FragmentManager getFragmentManager();
     method public android.content.Intent getIntent();
-    method public deprecated java.lang.Object getLastNonConfigurationInstance();
+    method public java.lang.Object getLastNonConfigurationInstance();
     method public android.view.LayoutInflater getLayoutInflater();
     method public android.app.LoaderManager getLoaderManager();
     method public java.lang.String getLocalClassName();
@@ -3543,7 +3543,7 @@
     method protected void onRestoreInstanceState(android.os.Bundle);
     method public void onRestoreInstanceState(android.os.Bundle, android.os.PersistableBundle);
     method protected void onResume();
-    method public deprecated java.lang.Object onRetainNonConfigurationInstance();
+    method public java.lang.Object onRetainNonConfigurationInstance();
     method protected void onSaveInstanceState(android.os.Bundle);
     method public void onSaveInstanceState(android.os.Bundle, android.os.PersistableBundle);
     method public boolean onSearchRequested(android.view.SearchEvent);
@@ -5983,6 +5983,7 @@
     field public static final int ENCRYPTION_STATUS_ACTIVATING = 2; // 0x2
     field public static final int ENCRYPTION_STATUS_ACTIVE = 3; // 0x3
     field public static final int ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY = 4; // 0x4
+    field public static final int ENCRYPTION_STATUS_ACTIVE_PER_USER = 5; // 0x5
     field public static final int ENCRYPTION_STATUS_INACTIVE = 1; // 0x1
     field public static final int ENCRYPTION_STATUS_UNSUPPORTED = 0; // 0x0
     field public static final java.lang.String EXTRA_ADD_EXPLANATION = "android.app.extra.ADD_EXPLANATION";
@@ -6376,8 +6377,8 @@
     method public long getTxPackets();
     method public int getUid();
     field public static final int ROAMING_ALL = -1; // 0xffffffff
-    field public static final int ROAMING_DEFAULT = 1; // 0x1
-    field public static final int ROAMING_ROAMING = 2; // 0x2
+    field public static final int ROAMING_NO = 1; // 0x1
+    field public static final int ROAMING_YES = 2; // 0x2
     field public static final int STATE_ALL = -1; // 0xffffffff
     field public static final int STATE_DEFAULT = 1; // 0x1
     field public static final int STATE_FOREGROUND = 2; // 0x2
@@ -8119,7 +8120,7 @@
     field public static final java.lang.String DOWNLOAD_SERVICE = "download";
     field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
     field public static final java.lang.String FINGERPRINT_SERVICE = "fingerprint";
-    field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardwareproperties";
+    field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
     field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
@@ -9462,6 +9463,7 @@
     method public int getShortcutIconResId(android.content.pm.ShortcutInfo, android.os.UserHandle);
     method public java.util.List<android.content.pm.ShortcutInfo> getShortcutInfo(java.lang.String, java.util.List<java.lang.String>, android.os.UserHandle);
     method public java.util.List<android.content.pm.ShortcutInfo> getShortcuts(android.content.pm.LauncherApps.ShortcutQuery, android.os.UserHandle);
+    method public boolean hasShortcutHostPermission();
     method public boolean isActivityEnabled(android.content.ComponentName, android.os.UserHandle);
     method public boolean isPackageEnabled(java.lang.String, android.os.UserHandle);
     method public void pinShortcuts(java.lang.String, java.util.List<java.lang.String>, android.os.UserHandle);
@@ -10125,7 +10127,6 @@
     method public static deprecated android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public int describeContents();
-    method public int getChangingConfigurations();
     method public int getColorForState(int[], int);
     method public int getDefaultColor();
     method public boolean isOpaque();
@@ -10137,6 +10138,7 @@
 
   public abstract class ComplexColor {
     ctor public ComplexColor();
+    method public int getChangingConfigurations();
     method public abstract int getDefaultColor();
     method public boolean isStateful();
   }
@@ -13044,9 +13046,9 @@
     method public void setPaddingMode(int);
     method public void setPaddingRelative(int, int, int, int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
+    field public static final int INSET_UNDEFINED = -2147483648; // 0x80000000
     field public static final int PADDING_MODE_NEST = 0; // 0x0
     field public static final int PADDING_MODE_STACK = 1; // 0x1
-    field public static final int UNDEFINED_INSET = -2147483648; // 0x80000000
   }
 
   public class LevelListDrawable extends android.graphics.drawable.DrawableContainer {
@@ -30831,6 +30833,7 @@
   public static class CallLog.Calls implements android.provider.BaseColumns {
     ctor public CallLog.Calls();
     method public static java.lang.String getLastOutgoingCall(android.content.Context);
+    field public static final int ANSWERED_EXTERNALLY_TYPE = 7; // 0x7
     field public static final int BLOCKED_TYPE = 6; // 0x6
     field public static final java.lang.String CACHED_FORMATTED_NUMBER = "formatted_number";
     field public static final java.lang.String CACHED_LOOKUP_URI = "lookup_uri";
@@ -30853,6 +30856,7 @@
     field public static final java.lang.String DURATION = "duration";
     field public static final java.lang.String EXTRA_CALL_TYPE_FILTER = "android.provider.extra.CALL_TYPE_FILTER";
     field public static final java.lang.String FEATURES = "features";
+    field public static final int FEATURES_PULLED_EXTERNALLY = 2; // 0x2
     field public static final int FEATURES_VIDEO = 1; // 0x1
     field public static final java.lang.String GEOCODED_LOCATION = "geocoded_location";
     field public static final int INCOMING_TYPE = 1; // 0x1
@@ -36129,9 +36133,11 @@
     method public void phoneAccountSelected(android.telecom.PhoneAccountHandle, boolean);
     method public void playDtmfTone(char);
     method public void postDialContinue(boolean);
+    method public void pullExternalCall();
     method public void registerCallback(android.telecom.Call.Callback);
     method public void registerCallback(android.telecom.Call.Callback, android.os.Handler);
     method public void reject(boolean, java.lang.String);
+    method public void sendCallEvent(java.lang.String, android.os.Bundle);
     method public void splitFromConference();
     method public void stopDtmfTone();
     method public void swapConference();
@@ -36145,6 +36151,7 @@
     field public static final int STATE_DISCONNECTING = 10; // 0xa
     field public static final int STATE_HOLDING = 3; // 0x3
     field public static final int STATE_NEW = 0; // 0x0
+    field public static final int STATE_PULLING_CALL = 11; // 0xb
     field public static final int STATE_RINGING = 2; // 0x2
     field public static final int STATE_SELECT_PHONE_ACCOUNT = 8; // 0x8
   }
@@ -36155,6 +36162,7 @@
     method public void onCannedTextResponsesLoaded(android.telecom.Call, java.util.List<java.lang.String>);
     method public void onChildrenChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
     method public void onConferenceableCallsChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
+    method public void onConnectionEvent(android.telecom.Call, java.lang.String, android.os.Bundle);
     method public void onDetailsChanged(android.telecom.Call, android.telecom.Call.Details);
     method public void onParentChanged(android.telecom.Call, android.telecom.Call);
     method public void onPostDialWait(android.telecom.Call, java.lang.String);
@@ -36185,6 +36193,7 @@
     method public static java.lang.String propertiesToString(int);
     field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 4194304; // 0x400000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
+    field public static final int CAPABILITY_CAN_PULL_CALL = 8388608; // 0x800000
     field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
     field public static final int CAPABILITY_HOLD = 1; // 0x1
     field public static final int CAPABILITY_MANAGE_CONFERENCE = 128; // 0x80
@@ -36204,6 +36213,7 @@
     field public static final int PROPERTY_EMERGENCY_CALLBACK_MODE = 4; // 0x4
     field public static final int PROPERTY_GENERIC_CONFERENCE = 2; // 0x2
     field public static final int PROPERTY_HIGH_DEF_AUDIO = 16; // 0x10
+    field public static final int PROPERTY_IS_EXTERNAL_CALL = 64; // 0x40
     field public static final int PROPERTY_WIFI = 8; // 0x8
     field public static final int PROPERTY_WORK_CALL = 32; // 0x20
   }
@@ -36318,15 +36328,19 @@
     method public void onAnswer(int);
     method public void onAnswer();
     method public void onCallAudioStateChanged(android.telecom.CallAudioState);
+    method public void onCallEvent(java.lang.String, android.os.Bundle);
     method public void onDisconnect();
     method public void onHold();
     method public void onPlayDtmfTone(char);
     method public void onPostDialContinue(boolean);
+    method public void onPullExternalCall();
     method public void onReject();
+    method public void onReject(java.lang.String);
     method public void onSeparate();
     method public void onStateChanged(int);
     method public void onStopDtmfTone();
     method public void onUnhold();
+    method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
     method public final void setActive();
     method public final void setAddress(android.net.Uri, int);
     method public final void setAudioModeIsVoip(boolean);
@@ -36350,9 +36364,12 @@
     method public static java.lang.String stateToString(int);
     field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 8388608; // 0x800000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
+    field public static final int CAPABILITY_CAN_PULL_CALL = 33554432; // 0x2000000
+    field public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000
     field public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000
     field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
     field public static final int CAPABILITY_HOLD = 1; // 0x1
+    field public static final int CAPABILITY_IS_EXTERNAL_CALL = 16777216; // 0x1000000
     field public static final int CAPABILITY_MANAGE_CONFERENCE = 128; // 0x80
     field public static final int CAPABILITY_MERGE_CONFERENCE = 4; // 0x4
     field public static final int CAPABILITY_MUTE = 64; // 0x40
@@ -36366,6 +36383,7 @@
     field public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 2048; // 0x800
     field public static final int CAPABILITY_SUPPORT_HOLD = 2; // 0x2
     field public static final int CAPABILITY_SWAP_CONFERENCE = 8; // 0x8
+    field public static final java.lang.String EVENT_CALL_PULL_FAILED = "android.telecom.event.CALL_PULL_FAILED";
     field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
     field public static final java.lang.String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
     field public static final java.lang.String EXTRA_LAST_FORWARDED_NUMBER = "android.telecom.extra.LAST_FORWARDED_NUMBER";
@@ -36375,6 +36393,7 @@
     field public static final int STATE_HOLDING = 5; // 0x5
     field public static final int STATE_INITIALIZING = 0; // 0x0
     field public static final int STATE_NEW = 1; // 0x1
+    field public static final int STATE_PULLING_CALL = 7; // 0x7
     field public static final int STATE_RINGING = 2; // 0x2
   }
 
@@ -36452,7 +36471,9 @@
     method public java.lang.String getReason();
     method public int getTone();
     method public void writeToParcel(android.os.Parcel, int);
+    field public static final int ANSWERED_ELSEWHERE = 11; // 0xb
     field public static final int BUSY = 7; // 0x7
+    field public static final int CALL_PULLED = 12; // 0xc
     field public static final int CANCELED = 4; // 0x4
     field public static final int CONNECTION_MANAGER_NOT_SUPPORTED = 10; // 0xa
     field public static final android.os.Parcelable.Creator<android.telecom.DisconnectCause> CREATOR;
@@ -36488,6 +36509,7 @@
     method public void onCallAudioStateChanged(android.telecom.CallAudioState);
     method public void onCallRemoved(android.telecom.Call);
     method public void onCanAddCallChanged(boolean);
+    method public void onConnectionEvent(android.telecom.Call, java.lang.String, android.os.Bundle);
     method public void onSilenceRinger();
     method public final void setAudioRoute(int);
     method public final void setMuted(boolean);
@@ -36638,6 +36660,7 @@
     method public boolean isVoipAudioMode();
     method public void playDtmfTone(char);
     method public void postDialContinue(boolean);
+    method public void pullExternalCall();
     method public void registerCallback(android.telecom.RemoteConnection.Callback);
     method public void registerCallback(android.telecom.RemoteConnection.Callback, android.os.Handler);
     method public void reject();
@@ -36654,6 +36677,7 @@
     method public void onConferenceChanged(android.telecom.RemoteConnection, android.telecom.RemoteConference);
     method public void onConferenceableConnectionsChanged(android.telecom.RemoteConnection, java.util.List<android.telecom.RemoteConnection>);
     method public void onConnectionCapabilitiesChanged(android.telecom.RemoteConnection, int);
+    method public void onConnectionEvent(android.telecom.RemoteConnection, java.lang.String, android.os.Bundle);
     method public void onDestroyed(android.telecom.RemoteConnection);
     method public void onDisconnected(android.telecom.RemoteConnection, android.telecom.DisconnectCause);
     method public void onExtrasChanged(android.telecom.RemoteConnection, android.os.Bundle);
@@ -36751,6 +36775,7 @@
     field public static final java.lang.String EXTRA_START_CALL_WITH_VIDEO_STATE = "android.telecom.extra.START_CALL_WITH_VIDEO_STATE";
     field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS";
     field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
+    field public static final java.lang.String METADATA_INCLUDE_EXTERNAL_CALLS = "android.telecom.INCLUDE_EXTERNAL_CALLS";
     field public static final java.lang.String METADATA_IN_CALL_SERVICE_RINGING = "android.telecom.IN_CALL_SERVICE_RINGING";
     field public static final java.lang.String METADATA_IN_CALL_SERVICE_UI = "android.telecom.IN_CALL_SERVICE_UI";
     field public static final int PRESENTATION_ALLOWED = 1; // 0x1
@@ -42658,6 +42683,7 @@
     method public void onStartTemporaryDetach();
     method public boolean onTouchEvent(android.view.MotionEvent);
     method public boolean onTrackballEvent(android.view.MotionEvent);
+    method public void onVisibilityAggregated(android.view.View, int);
     method protected void onVisibilityChanged(android.view.View, int);
     method public void onWindowFocusChanged(boolean);
     method public void onWindowSystemUiVisibilityChanged(int);
@@ -57417,6 +57443,7 @@
     method public void ensureCapacity(int);
     method public void forEach(java.util.function.Consumer<? super E>);
     method public E get(int);
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
     method public int size();
     method public java.util.Spliterator<E> spliterator();
     method public void trimToSize();
@@ -57501,6 +57528,24 @@
     method public static int hashCode(float[]);
     method public static int hashCode(double[]);
     method public static int hashCode(java.lang.Object[]);
+    method public static void parallelSort(byte[]);
+    method public static void parallelSort(byte[], int, int);
+    method public static void parallelSort(char[]);
+    method public static void parallelSort(char[], int, int);
+    method public static void parallelSort(short[]);
+    method public static void parallelSort(short[], int, int);
+    method public static void parallelSort(int[]);
+    method public static void parallelSort(int[], int, int);
+    method public static void parallelSort(long[]);
+    method public static void parallelSort(long[], int, int);
+    method public static void parallelSort(float[]);
+    method public static void parallelSort(float[], int, int);
+    method public static void parallelSort(double[]);
+    method public static void parallelSort(double[], int, int);
+    method public static void parallelSort(T[]);
+    method public static void parallelSort(T[], int, int);
+    method public static void parallelSort(T[], java.util.Comparator<? super T>);
+    method public static void parallelSort(T[], int, int, java.util.Comparator<? super T>);
     method public static void sort(int[]);
     method public static void sort(int[], int, int);
     method public static void sort(long[]);
@@ -57688,6 +57733,7 @@
     method public abstract java.util.Iterator<E> iterator();
     method public abstract boolean remove(java.lang.Object);
     method public abstract boolean removeAll(java.util.Collection<?>);
+    method public default boolean removeIf(java.util.function.Predicate<? super E>);
     method public abstract boolean retainAll(java.util.Collection<?>);
     method public abstract int size();
     method public abstract java.lang.Object[] toArray();
@@ -58321,18 +58367,28 @@
 
   public abstract interface Map {
     method public abstract void clear();
+    method public default V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public default V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public default V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public abstract boolean containsKey(java.lang.Object);
     method public abstract boolean containsValue(java.lang.Object);
     method public abstract java.util.Set<java.util.Map.Entry<K, V>> entrySet();
     method public abstract boolean equals(java.lang.Object);
     method public default void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public abstract V get(java.lang.Object);
+    method public default V getOrDefault(java.lang.Object, V);
     method public abstract int hashCode();
     method public abstract boolean isEmpty();
     method public abstract java.util.Set<K> keySet();
+    method public default V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public abstract V put(K, V);
     method public abstract void putAll(java.util.Map<? extends K, ? extends V>);
+    method public default V putIfAbsent(K, V);
     method public abstract V remove(java.lang.Object);
+    method public default boolean remove(java.lang.Object, java.lang.Object);
+    method public default boolean replace(K, V, V);
+    method public default V replace(K, V);
+    method public default void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public abstract int size();
     method public abstract java.util.Collection<V> values();
   }
@@ -58340,6 +58396,8 @@
   public static abstract interface Map.Entry {
     method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByKey();
     method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByKey(java.util.Comparator<? super K>);
+    method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByValue();
+    method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByValue(java.util.Comparator<? super V>);
     method public abstract boolean equals(java.lang.Object);
     method public abstract K getKey();
     method public abstract V getValue();
@@ -59070,6 +59128,7 @@
     method public synchronized void removeAllElements();
     method public synchronized boolean removeElement(java.lang.Object);
     method public synchronized void removeElementAt(int);
+    method public synchronized boolean removeIf(java.util.function.Predicate<? super E>);
     method public synchronized void setElementAt(E, int);
     method public synchronized void setSize(int);
     method public synchronized int size();
@@ -59121,6 +59180,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -59184,6 +59244,78 @@
     ctor public CancellationException(java.lang.String);
   }
 
+  public class CompletableFuture implements java.util.concurrent.CompletionStage java.util.concurrent.Future {
+    ctor public CompletableFuture();
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
+    method public static java.util.concurrent.CompletableFuture<java.lang.Void> allOf(java.util.concurrent.CompletableFuture<?>...);
+    method public static java.util.concurrent.CompletableFuture<java.lang.Object> anyOf(java.util.concurrent.CompletableFuture<?>...);
+    method public java.util.concurrent.CompletableFuture<U> applyToEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>);
+    method public java.util.concurrent.CompletableFuture<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>);
+    method public java.util.concurrent.CompletableFuture<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>, java.util.concurrent.Executor);
+    method public boolean cancel(boolean);
+    method public boolean complete(T);
+    method public boolean completeExceptionally(java.lang.Throwable);
+    method public static java.util.concurrent.CompletableFuture<U> completedFuture(U);
+    method public java.util.concurrent.CompletableFuture<T> exceptionally(java.util.function.Function<java.lang.Throwable, ? extends T>);
+    method public T get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
+    method public T get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+    method public T getNow(T);
+    method public int getNumberOfDependents();
+    method public java.util.concurrent.CompletableFuture<U> handle(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>);
+    method public java.util.concurrent.CompletableFuture<U> handleAsync(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>);
+    method public java.util.concurrent.CompletableFuture<U> handleAsync(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>, java.util.concurrent.Executor);
+    method public boolean isCancelled();
+    method public boolean isCompletedExceptionally();
+    method public boolean isDone();
+    method public T join();
+    method public void obtrudeException(java.lang.Throwable);
+    method public void obtrudeValue(T);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBoth(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEither(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable, java.util.concurrent.Executor);
+    method public static java.util.concurrent.CompletableFuture<java.lang.Void> runAsync(java.lang.Runnable);
+    method public static java.util.concurrent.CompletableFuture<java.lang.Void> runAsync(java.lang.Runnable, java.util.concurrent.Executor);
+    method public static java.util.concurrent.CompletableFuture<U> supplyAsync(java.util.function.Supplier<U>);
+    method public static java.util.concurrent.CompletableFuture<U> supplyAsync(java.util.function.Supplier<U>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAccept(java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBoth(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<U> thenApply(java.util.function.Function<? super T, ? extends U>);
+    method public java.util.concurrent.CompletableFuture<U> thenApplyAsync(java.util.function.Function<? super T, ? extends U>);
+    method public java.util.concurrent.CompletableFuture<U> thenApplyAsync(java.util.function.Function<? super T, ? extends U>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<V> thenCombine(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>);
+    method public java.util.concurrent.CompletableFuture<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>);
+    method public java.util.concurrent.CompletableFuture<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<U> thenCompose(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>);
+    method public java.util.concurrent.CompletableFuture<U> thenComposeAsync(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>);
+    method public java.util.concurrent.CompletableFuture<U> thenComposeAsync(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenRun(java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenRunAsync(java.lang.Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenRunAsync(java.lang.Runnable, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<T> toCompletableFuture();
+    method public java.util.concurrent.CompletableFuture<T> whenComplete(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>);
+    method public java.util.concurrent.CompletableFuture<T> whenCompleteAsync(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>);
+    method public java.util.concurrent.CompletableFuture<T> whenCompleteAsync(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>, java.util.concurrent.Executor);
+  }
+
+  public static abstract interface CompletableFuture.AsynchronousCompletionTask {
+  }
+
+  public class CompletionException extends java.lang.RuntimeException {
+    ctor protected CompletionException();
+    ctor protected CompletionException(java.lang.String);
+    ctor public CompletionException(java.lang.String, java.lang.Throwable);
+    ctor public CompletionException(java.lang.Throwable);
+  }
+
   public abstract interface CompletionService {
     method public abstract java.util.concurrent.Future<V> poll();
     method public abstract java.util.concurrent.Future<V> poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
@@ -59192,20 +59324,130 @@
     method public abstract java.util.concurrent.Future<V> take() throws java.lang.InterruptedException;
   }
 
+  public abstract interface CompletionStage {
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> acceptEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<U> applyToEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>);
+    method public abstract java.util.concurrent.CompletionStage<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>);
+    method public abstract java.util.concurrent.CompletionStage<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T, U>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<T> exceptionally(java.util.function.Function<java.lang.Throwable, ? extends T>);
+    method public abstract java.util.concurrent.CompletionStage<U> handle(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>);
+    method public abstract java.util.concurrent.CompletionStage<U> handleAsync(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>);
+    method public abstract java.util.concurrent.CompletionStage<U> handleAsync(java.util.function.BiFunction<? super T, java.lang.Throwable, ? extends U>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterBoth(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterEither(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, java.lang.Runnable, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAccept(java.util.function.Consumer<? super T>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptBoth(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T, ? super U>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<U> thenApply(java.util.function.Function<? super T, ? extends U>);
+    method public abstract java.util.concurrent.CompletionStage<U> thenApplyAsync(java.util.function.Function<? super T, ? extends U>);
+    method public abstract java.util.concurrent.CompletionStage<U> thenApplyAsync(java.util.function.Function<? super T, ? extends U>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<V> thenCombine(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>);
+    method public abstract java.util.concurrent.CompletionStage<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>);
+    method public abstract java.util.concurrent.CompletionStage<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T, ? super U, ? extends V>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<U> thenCompose(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>);
+    method public abstract java.util.concurrent.CompletionStage<U> thenComposeAsync(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>);
+    method public abstract java.util.concurrent.CompletionStage<U> thenComposeAsync(java.util.function.Function<? super T, ? extends java.util.concurrent.CompletionStage<U>>, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenRun(java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenRunAsync(java.lang.Runnable);
+    method public abstract java.util.concurrent.CompletionStage<java.lang.Void> thenRunAsync(java.lang.Runnable, java.util.concurrent.Executor);
+    method public abstract java.util.concurrent.CompletableFuture<T> toCompletableFuture();
+    method public abstract java.util.concurrent.CompletionStage<T> whenComplete(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>);
+    method public abstract java.util.concurrent.CompletionStage<T> whenCompleteAsync(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>);
+    method public abstract java.util.concurrent.CompletionStage<T> whenCompleteAsync(java.util.function.BiConsumer<? super T, ? super java.lang.Throwable>, java.util.concurrent.Executor);
+  }
+
   public class ConcurrentHashMap extends java.util.AbstractMap implements java.util.concurrent.ConcurrentMap java.io.Serializable {
     ctor public ConcurrentHashMap();
     ctor public ConcurrentHashMap(int);
     ctor public ConcurrentHashMap(java.util.Map<? extends K, ? extends V>);
     ctor public ConcurrentHashMap(int, float);
     ctor public ConcurrentHashMap(int, float, int);
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public boolean contains(java.lang.Object);
     method public java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public void forEach(long, java.util.function.BiConsumer<? super K, ? super V>);
+    method public void forEach(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.Consumer<? super U>);
+    method public void forEachEntry(long, java.util.function.Consumer<? super java.util.Map.Entry<K, V>>);
+    method public void forEachEntry(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>, java.util.function.Consumer<? super U>);
+    method public void forEachKey(long, java.util.function.Consumer<? super K>);
+    method public void forEachKey(long, java.util.function.Function<? super K, ? extends U>, java.util.function.Consumer<? super U>);
+    method public void forEachValue(long, java.util.function.Consumer<? super V>);
+    method public void forEachValue(long, java.util.function.Function<? super V, ? extends U>, java.util.function.Consumer<? super U>);
+    method public V getOrDefault(java.lang.Object, V);
+    method public java.util.concurrent.ConcurrentHashMap.KeySetView<K, V> keySet(V);
     method public java.util.Enumeration<K> keys();
+    method public long mappingCount();
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
+    method public static java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet();
+    method public static java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet(int);
     method public V putIfAbsent(K, V);
+    method public U reduce(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
+    method public java.util.Map.Entry<K, V> reduceEntries(long, java.util.function.BiFunction<java.util.Map.Entry<K, V>, java.util.Map.Entry<K, V>, ? extends java.util.Map.Entry<K, V>>);
+    method public U reduceEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
+    method public double reduceEntriesToDouble(long, java.util.function.ToDoubleFunction<java.util.Map.Entry<K, V>>, double, java.util.function.DoubleBinaryOperator);
+    method public int reduceEntriesToInt(long, java.util.function.ToIntFunction<java.util.Map.Entry<K, V>>, int, java.util.function.IntBinaryOperator);
+    method public long reduceEntriesToLong(long, java.util.function.ToLongFunction<java.util.Map.Entry<K, V>>, long, java.util.function.LongBinaryOperator);
+    method public K reduceKeys(long, java.util.function.BiFunction<? super K, ? super K, ? extends K>);
+    method public U reduceKeys(long, java.util.function.Function<? super K, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
+    method public double reduceKeysToDouble(long, java.util.function.ToDoubleFunction<? super K>, double, java.util.function.DoubleBinaryOperator);
+    method public int reduceKeysToInt(long, java.util.function.ToIntFunction<? super K>, int, java.util.function.IntBinaryOperator);
+    method public long reduceKeysToLong(long, java.util.function.ToLongFunction<? super K>, long, java.util.function.LongBinaryOperator);
+    method public double reduceToDouble(long, java.util.function.ToDoubleBiFunction<? super K, ? super V>, double, java.util.function.DoubleBinaryOperator);
+    method public int reduceToInt(long, java.util.function.ToIntBiFunction<? super K, ? super V>, int, java.util.function.IntBinaryOperator);
+    method public long reduceToLong(long, java.util.function.ToLongBiFunction<? super K, ? super V>, long, java.util.function.LongBinaryOperator);
+    method public V reduceValues(long, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
+    method public U reduceValues(long, java.util.function.Function<? super V, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
+    method public double reduceValuesToDouble(long, java.util.function.ToDoubleFunction<? super V>, double, java.util.function.DoubleBinaryOperator);
+    method public int reduceValuesToInt(long, java.util.function.ToIntFunction<? super V>, int, java.util.function.IntBinaryOperator);
+    method public long reduceValuesToLong(long, java.util.function.ToLongFunction<? super V>, long, java.util.function.LongBinaryOperator);
     method public boolean remove(java.lang.Object, java.lang.Object);
     method public boolean replace(K, V, V);
     method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public U search(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>);
+    method public U searchEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>);
+    method public U searchKeys(long, java.util.function.Function<? super K, ? extends U>);
+    method public U searchValues(long, java.util.function.Function<? super V, ? extends U>);
+  }
+
+   static abstract class ConcurrentHashMap.CollectionView implements java.util.Collection java.io.Serializable {
+    method public final void clear();
+    method public abstract boolean contains(java.lang.Object);
+    method public final boolean containsAll(java.util.Collection<?>);
+    method public java.util.concurrent.ConcurrentHashMap<K, V> getMap();
+    method public final boolean isEmpty();
+    method public abstract java.util.Iterator<E> iterator();
+    method public abstract boolean remove(java.lang.Object);
+    method public final boolean removeAll(java.util.Collection<?>);
+    method public final boolean retainAll(java.util.Collection<?>);
+    method public final int size();
+    method public final java.lang.Object[] toArray();
+    method public final T[] toArray(T[]);
+    method public final java.lang.String toString();
+  }
+
+  public static class ConcurrentHashMap.KeySetView extends java.util.concurrent.ConcurrentHashMap.CollectionView implements java.io.Serializable java.util.Set {
+    method public boolean add(K);
+    method public boolean addAll(java.util.Collection<? extends K>);
+    method public boolean contains(java.lang.Object);
+    method public void forEach(java.util.function.Consumer<? super K>);
+    method public V getMappedValue();
+    method public java.util.Iterator<K> iterator();
+    method public boolean remove(java.lang.Object);
+    method public java.util.Spliterator<K> spliterator();
   }
 
   public class ConcurrentLinkedDeque extends java.util.AbstractCollection implements java.util.Deque java.io.Serializable {
@@ -59235,6 +59477,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ConcurrentLinkedQueue extends java.util.AbstractQueue implements java.util.Queue java.io.Serializable {
@@ -59245,6 +59488,7 @@
     method public E peek();
     method public E poll();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface ConcurrentMap implements java.util.Map {
@@ -59276,6 +59520,9 @@
     method public K ceilingKey(K);
     method public java.util.concurrent.ConcurrentSkipListMap<K, V> clone();
     method public java.util.Comparator<? super K> comparator();
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> descendingKeySet();
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> descendingMap();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
@@ -59283,6 +59530,8 @@
     method public K firstKey();
     method public java.util.Map.Entry<K, V> floorEntry(K);
     method public K floorKey(K);
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public V getOrDefault(java.lang.Object, V);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
@@ -59291,6 +59540,7 @@
     method public K lastKey();
     method public java.util.Map.Entry<K, V> lowerEntry(K);
     method public K lowerKey(K);
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> navigableKeySet();
     method public java.util.Map.Entry<K, V> pollFirstEntry();
     method public java.util.Map.Entry<K, V> pollLastEntry();
@@ -59298,6 +59548,7 @@
     method public boolean remove(java.lang.Object, java.lang.Object);
     method public boolean replace(K, V, V);
     method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, K);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> tailMap(K, boolean);
@@ -59325,6 +59576,7 @@
     method public E pollFirst();
     method public E pollLast();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
     method public java.util.NavigableSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -59335,31 +59587,34 @@
     ctor public CopyOnWriteArrayList();
     ctor public CopyOnWriteArrayList(java.util.Collection<? extends E>);
     ctor public CopyOnWriteArrayList(E[]);
-    method public synchronized boolean add(E);
-    method public synchronized void add(int, E);
-    method public synchronized boolean addAll(java.util.Collection<? extends E>);
-    method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
-    method public synchronized int addAllAbsent(java.util.Collection<? extends E>);
-    method public synchronized boolean addIfAbsent(E);
-    method public synchronized void clear();
+    method public boolean add(E);
+    method public void add(int, E);
+    method public boolean addAll(java.util.Collection<? extends E>);
+    method public boolean addAll(int, java.util.Collection<? extends E>);
+    method public int addAllAbsent(java.util.Collection<? extends E>);
+    method public boolean addIfAbsent(E);
+    method public void clear();
     method public java.lang.Object clone();
     method public boolean contains(java.lang.Object);
     method public boolean containsAll(java.util.Collection<?>);
+    method public void forEach(java.util.function.Consumer<? super E>);
     method public E get(int);
-    method public int indexOf(E, int);
     method public int indexOf(java.lang.Object);
+    method public int indexOf(E, int);
     method public boolean isEmpty();
     method public java.util.Iterator<E> iterator();
-    method public int lastIndexOf(E, int);
     method public int lastIndexOf(java.lang.Object);
-    method public java.util.ListIterator<E> listIterator(int);
+    method public int lastIndexOf(E, int);
     method public java.util.ListIterator<E> listIterator();
-    method public synchronized E remove(int);
-    method public synchronized boolean remove(java.lang.Object);
-    method public synchronized boolean removeAll(java.util.Collection<?>);
-    method public synchronized boolean retainAll(java.util.Collection<?>);
-    method public synchronized E set(int, E);
+    method public java.util.ListIterator<E> listIterator(int);
+    method public E remove(int);
+    method public boolean remove(java.lang.Object);
+    method public boolean removeAll(java.util.Collection<?>);
+    method public void replaceAll(java.util.function.UnaryOperator<E>);
+    method public boolean retainAll(java.util.Collection<?>);
+    method public E set(int, E);
     method public int size();
+    method public void sort(java.util.Comparator<? super E>);
     method public java.util.List<E> subList(int, int);
     method public java.lang.Object[] toArray();
     method public T[] toArray(T[]);
@@ -59368,8 +59623,11 @@
   public class CopyOnWriteArraySet extends java.util.AbstractSet implements java.io.Serializable {
     ctor public CopyOnWriteArraySet();
     ctor public CopyOnWriteArraySet(java.util.Collection<? extends E>);
+    method public void forEach(java.util.function.Consumer<? super E>);
     method public java.util.Iterator<E> iterator();
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class CountDownLatch {
@@ -59380,6 +59638,32 @@
     method public long getCount();
   }
 
+  public abstract class CountedCompleter extends java.util.concurrent.ForkJoinTask {
+    ctor protected CountedCompleter(java.util.concurrent.CountedCompleter<?>, int);
+    ctor protected CountedCompleter(java.util.concurrent.CountedCompleter<?>);
+    ctor protected CountedCompleter();
+    method public final void addToPendingCount(int);
+    method public final boolean compareAndSetPendingCount(int, int);
+    method public void complete(T);
+    method public abstract void compute();
+    method public final int decrementPendingCountUnlessZero();
+    method protected final boolean exec();
+    method public final java.util.concurrent.CountedCompleter<?> firstComplete();
+    method public final java.util.concurrent.CountedCompleter<?> getCompleter();
+    method public final int getPendingCount();
+    method public T getRawResult();
+    method public final java.util.concurrent.CountedCompleter<?> getRoot();
+    method public final void helpComplete(int);
+    method public final java.util.concurrent.CountedCompleter<?> nextComplete();
+    method public void onCompletion(java.util.concurrent.CountedCompleter<?>);
+    method public boolean onExceptionalCompletion(java.lang.Throwable, java.util.concurrent.CountedCompleter<?>);
+    method public final void propagateCompletion();
+    method public final void quietlyCompleteRoot();
+    method public final void setPendingCount(int);
+    method protected void setRawResult(T);
+    method public final void tryComplete();
+  }
+
   public class CyclicBarrier {
     ctor public CyclicBarrier(int, java.lang.Runnable);
     ctor public CyclicBarrier(int);
@@ -59470,6 +59754,8 @@
     method public static java.util.concurrent.ExecutorService newSingleThreadExecutor(java.util.concurrent.ThreadFactory);
     method public static java.util.concurrent.ScheduledExecutorService newSingleThreadScheduledExecutor();
     method public static java.util.concurrent.ScheduledExecutorService newSingleThreadScheduledExecutor(java.util.concurrent.ThreadFactory);
+    method public static java.util.concurrent.ExecutorService newWorkStealingPool(int);
+    method public static java.util.concurrent.ExecutorService newWorkStealingPool();
     method public static java.util.concurrent.Callable<T> privilegedCallable(java.util.concurrent.Callable<T>);
     method public static java.util.concurrent.Callable<T> privilegedCallableUsingCurrentClassLoader(java.util.concurrent.Callable<T>);
     method public static java.util.concurrent.ThreadFactory privilegedThreadFactory();
@@ -59483,11 +59769,13 @@
     ctor public ForkJoinPool(int, java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory, java.lang.Thread.UncaughtExceptionHandler, boolean);
     method public boolean awaitQuiescence(long, java.util.concurrent.TimeUnit);
     method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public static java.util.concurrent.ForkJoinPool commonPool();
     method protected int drainTasksTo(java.util.Collection<? super java.util.concurrent.ForkJoinTask<?>>);
     method public void execute(java.util.concurrent.ForkJoinTask<?>);
     method public void execute(java.lang.Runnable);
     method public int getActiveThreadCount();
     method public boolean getAsyncMode();
+    method public static int getCommonPoolParallelism();
     method public java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory getFactory();
     method public int getParallelism();
     method public int getPoolSize();
@@ -59525,6 +59813,7 @@
     method public static java.util.concurrent.ForkJoinTask<T> adapt(java.lang.Runnable, T);
     method public static java.util.concurrent.ForkJoinTask<T> adapt(java.util.concurrent.Callable<? extends T>);
     method public boolean cancel(boolean);
+    method public final boolean compareAndSetForkJoinTaskTag(short, short);
     method public void complete(V);
     method public void completeExceptionally(java.lang.Throwable);
     method protected abstract boolean exec();
@@ -59532,6 +59821,7 @@
     method public final V get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
     method public final V get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
     method public final java.lang.Throwable getException();
+    method public final short getForkJoinTaskTag();
     method public static java.util.concurrent.ForkJoinPool getPool();
     method public static int getQueuedTaskCount();
     method public abstract V getRawResult();
@@ -59550,9 +59840,11 @@
     method protected static java.util.concurrent.ForkJoinTask<?> peekNextLocalTask();
     method protected static java.util.concurrent.ForkJoinTask<?> pollNextLocalTask();
     method protected static java.util.concurrent.ForkJoinTask<?> pollTask();
+    method public final void quietlyComplete();
     method public final void quietlyInvoke();
     method public final void quietlyJoin();
     method public void reinitialize();
+    method public final short setForkJoinTaskTag(short);
     method protected abstract void setRawResult(V);
     method public boolean tryUnfork();
   }
@@ -59626,6 +59918,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public E takeFirst() throws java.lang.InterruptedException;
     method public E takeLast() throws java.lang.InterruptedException;
@@ -59646,6 +59939,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -59665,6 +59959,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public void transfer(E) throws java.lang.InterruptedException;
     method public boolean tryTransfer(E);
@@ -59712,6 +60007,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -59815,6 +60111,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -59944,112 +60241,136 @@
   public class AtomicInteger extends java.lang.Number implements java.io.Serializable {
     ctor public AtomicInteger(int);
     ctor public AtomicInteger();
+    method public final int accumulateAndGet(int, java.util.function.IntBinaryOperator);
     method public final int addAndGet(int);
     method public final boolean compareAndSet(int, int);
     method public final int decrementAndGet();
     method public double doubleValue();
     method public float floatValue();
     method public final int get();
+    method public final int getAndAccumulate(int, java.util.function.IntBinaryOperator);
     method public final int getAndAdd(int);
     method public final int getAndDecrement();
     method public final int getAndIncrement();
     method public final int getAndSet(int);
+    method public final int getAndUpdate(java.util.function.IntUnaryOperator);
     method public final int incrementAndGet();
     method public int intValue();
     method public final void lazySet(int);
     method public long longValue();
     method public final void set(int);
+    method public final int updateAndGet(java.util.function.IntUnaryOperator);
     method public final boolean weakCompareAndSet(int, int);
   }
 
   public class AtomicIntegerArray implements java.io.Serializable {
     ctor public AtomicIntegerArray(int);
     ctor public AtomicIntegerArray(int[]);
+    method public final int accumulateAndGet(int, int, java.util.function.IntBinaryOperator);
     method public final int addAndGet(int, int);
     method public final boolean compareAndSet(int, int, int);
     method public final int decrementAndGet(int);
     method public final int get(int);
+    method public final int getAndAccumulate(int, int, java.util.function.IntBinaryOperator);
     method public final int getAndAdd(int, int);
     method public final int getAndDecrement(int);
     method public final int getAndIncrement(int);
     method public final int getAndSet(int, int);
+    method public final int getAndUpdate(int, java.util.function.IntUnaryOperator);
     method public final int incrementAndGet(int);
     method public final void lazySet(int, int);
     method public final int length();
     method public final void set(int, int);
+    method public final int updateAndGet(int, java.util.function.IntUnaryOperator);
     method public final boolean weakCompareAndSet(int, int, int);
   }
 
   public abstract class AtomicIntegerFieldUpdater {
     ctor protected AtomicIntegerFieldUpdater();
+    method public final int accumulateAndGet(T, int, java.util.function.IntBinaryOperator);
     method public int addAndGet(T, int);
     method public abstract boolean compareAndSet(T, int, int);
     method public int decrementAndGet(T);
     method public abstract int get(T);
+    method public final int getAndAccumulate(T, int, java.util.function.IntBinaryOperator);
     method public int getAndAdd(T, int);
     method public int getAndDecrement(T);
     method public int getAndIncrement(T);
     method public int getAndSet(T, int);
+    method public final int getAndUpdate(T, java.util.function.IntUnaryOperator);
     method public int incrementAndGet(T);
     method public abstract void lazySet(T, int);
     method public static java.util.concurrent.atomic.AtomicIntegerFieldUpdater<U> newUpdater(java.lang.Class<U>, java.lang.String);
     method public abstract void set(T, int);
+    method public final int updateAndGet(T, java.util.function.IntUnaryOperator);
     method public abstract boolean weakCompareAndSet(T, int, int);
   }
 
   public class AtomicLong extends java.lang.Number implements java.io.Serializable {
     ctor public AtomicLong(long);
     ctor public AtomicLong();
+    method public final long accumulateAndGet(long, java.util.function.LongBinaryOperator);
     method public final long addAndGet(long);
     method public final boolean compareAndSet(long, long);
     method public final long decrementAndGet();
     method public double doubleValue();
     method public float floatValue();
     method public final long get();
+    method public final long getAndAccumulate(long, java.util.function.LongBinaryOperator);
     method public final long getAndAdd(long);
     method public final long getAndDecrement();
     method public final long getAndIncrement();
     method public final long getAndSet(long);
+    method public final long getAndUpdate(java.util.function.LongUnaryOperator);
     method public final long incrementAndGet();
     method public int intValue();
     method public final void lazySet(long);
     method public long longValue();
     method public final void set(long);
+    method public final long updateAndGet(java.util.function.LongUnaryOperator);
     method public final boolean weakCompareAndSet(long, long);
   }
 
   public class AtomicLongArray implements java.io.Serializable {
     ctor public AtomicLongArray(int);
     ctor public AtomicLongArray(long[]);
+    method public final long accumulateAndGet(int, long, java.util.function.LongBinaryOperator);
     method public long addAndGet(int, long);
     method public final boolean compareAndSet(int, long, long);
     method public final long decrementAndGet(int);
     method public final long get(int);
+    method public final long getAndAccumulate(int, long, java.util.function.LongBinaryOperator);
     method public final long getAndAdd(int, long);
     method public final long getAndDecrement(int);
     method public final long getAndIncrement(int);
     method public final long getAndSet(int, long);
+    method public final long getAndUpdate(int, java.util.function.LongUnaryOperator);
     method public final long incrementAndGet(int);
     method public final void lazySet(int, long);
     method public final int length();
     method public final void set(int, long);
+    method public final long updateAndGet(int, java.util.function.LongUnaryOperator);
     method public final boolean weakCompareAndSet(int, long, long);
   }
 
   public abstract class AtomicLongFieldUpdater {
     ctor protected AtomicLongFieldUpdater();
+    method public final long accumulateAndGet(T, long, java.util.function.LongBinaryOperator);
     method public long addAndGet(T, long);
     method public abstract boolean compareAndSet(T, long, long);
     method public long decrementAndGet(T);
     method public abstract long get(T);
+    method public final long getAndAccumulate(T, long, java.util.function.LongBinaryOperator);
     method public long getAndAdd(T, long);
     method public long getAndDecrement(T);
     method public long getAndIncrement(T);
     method public long getAndSet(T, long);
+    method public final long getAndUpdate(T, java.util.function.LongUnaryOperator);
     method public long incrementAndGet(T);
     method public abstract void lazySet(T, long);
     method public static java.util.concurrent.atomic.AtomicLongFieldUpdater<U> newUpdater(java.lang.Class<U>, java.lang.String);
     method public abstract void set(T, long);
+    method public final long updateAndGet(T, java.util.function.LongUnaryOperator);
     method public abstract boolean weakCompareAndSet(T, long, long);
   }
 
@@ -60067,34 +60388,46 @@
   public class AtomicReference implements java.io.Serializable {
     ctor public AtomicReference(V);
     ctor public AtomicReference();
+    method public final V accumulateAndGet(V, java.util.function.BinaryOperator<V>);
     method public final boolean compareAndSet(V, V);
     method public final V get();
+    method public final V getAndAccumulate(V, java.util.function.BinaryOperator<V>);
     method public final V getAndSet(V);
+    method public final V getAndUpdate(java.util.function.UnaryOperator<V>);
     method public final void lazySet(V);
     method public final void set(V);
+    method public final V updateAndGet(java.util.function.UnaryOperator<V>);
     method public final boolean weakCompareAndSet(V, V);
   }
 
   public class AtomicReferenceArray implements java.io.Serializable {
     ctor public AtomicReferenceArray(int);
     ctor public AtomicReferenceArray(E[]);
+    method public final E accumulateAndGet(int, E, java.util.function.BinaryOperator<E>);
     method public final boolean compareAndSet(int, E, E);
     method public final E get(int);
+    method public final E getAndAccumulate(int, E, java.util.function.BinaryOperator<E>);
     method public final E getAndSet(int, E);
+    method public final E getAndUpdate(int, java.util.function.UnaryOperator<E>);
     method public final void lazySet(int, E);
     method public final int length();
     method public final void set(int, E);
+    method public final E updateAndGet(int, java.util.function.UnaryOperator<E>);
     method public final boolean weakCompareAndSet(int, E, E);
   }
 
   public abstract class AtomicReferenceFieldUpdater {
     ctor protected AtomicReferenceFieldUpdater();
+    method public final V accumulateAndGet(T, V, java.util.function.BinaryOperator<V>);
     method public abstract boolean compareAndSet(T, V, V);
     method public abstract V get(T);
+    method public final V getAndAccumulate(T, V, java.util.function.BinaryOperator<V>);
     method public V getAndSet(T, V);
+    method public final V getAndUpdate(T, java.util.function.UnaryOperator<V>);
     method public abstract void lazySet(T, V);
     method public static java.util.concurrent.atomic.AtomicReferenceFieldUpdater<U, W> newUpdater(java.lang.Class<U>, java.lang.Class<W>, java.lang.String);
     method public abstract void set(T, V);
+    method public final V updateAndGet(T, java.util.function.UnaryOperator<V>);
     method public abstract boolean weakCompareAndSet(T, V, V);
   }
 
@@ -60109,6 +60442,59 @@
     method public boolean weakCompareAndSet(V, V, int, int);
   }
 
+  public class DoubleAccumulator extends java.util.concurrent.atomic.Striped64 implements java.io.Serializable {
+    ctor public DoubleAccumulator(java.util.function.DoubleBinaryOperator, double);
+    method public void accumulate(double);
+    method public double doubleValue();
+    method public float floatValue();
+    method public double get();
+    method public double getThenReset();
+    method public int intValue();
+    method public long longValue();
+    method public void reset();
+  }
+
+  public class DoubleAdder extends java.util.concurrent.atomic.Striped64 implements java.io.Serializable {
+    ctor public DoubleAdder();
+    method public void add(double);
+    method public double doubleValue();
+    method public float floatValue();
+    method public int intValue();
+    method public long longValue();
+    method public void reset();
+    method public double sum();
+    method public double sumThenReset();
+  }
+
+  public class LongAccumulator extends java.util.concurrent.atomic.Striped64 implements java.io.Serializable {
+    ctor public LongAccumulator(java.util.function.LongBinaryOperator, long);
+    method public void accumulate(long);
+    method public double doubleValue();
+    method public float floatValue();
+    method public long get();
+    method public long getThenReset();
+    method public int intValue();
+    method public long longValue();
+    method public void reset();
+  }
+
+  public class LongAdder extends java.util.concurrent.atomic.Striped64 implements java.io.Serializable {
+    ctor public LongAdder();
+    method public void add(long);
+    method public void decrement();
+    method public double doubleValue();
+    method public float floatValue();
+    method public void increment();
+    method public int intValue();
+    method public long longValue();
+    method public void reset();
+    method public long sum();
+    method public long sumThenReset();
+  }
+
+   abstract class Striped64 extends java.lang.Number {
+  }
+
 }
 
 package java.util.concurrent.locks {
@@ -60316,6 +60702,34 @@
     method public void unlock();
   }
 
+  public class StampedLock implements java.io.Serializable {
+    ctor public StampedLock();
+    method public java.util.concurrent.locks.Lock asReadLock();
+    method public java.util.concurrent.locks.ReadWriteLock asReadWriteLock();
+    method public java.util.concurrent.locks.Lock asWriteLock();
+    method public int getReadLockCount();
+    method public boolean isReadLocked();
+    method public boolean isWriteLocked();
+    method public long readLock();
+    method public long readLockInterruptibly() throws java.lang.InterruptedException;
+    method public long tryConvertToOptimisticRead(long);
+    method public long tryConvertToReadLock(long);
+    method public long tryConvertToWriteLock(long);
+    method public long tryOptimisticRead();
+    method public long tryReadLock();
+    method public long tryReadLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public boolean tryUnlockRead();
+    method public boolean tryUnlockWrite();
+    method public long tryWriteLock();
+    method public long tryWriteLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public void unlock(long);
+    method public void unlockRead(long);
+    method public void unlockWrite(long);
+    method public boolean validate(long);
+    method public long writeLock();
+    method public long writeLockInterruptibly() throws java.lang.InterruptedException;
+  }
+
 }
 
 package java.util.function {
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index 844063c..8e31d32 100644
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -16,6 +16,7 @@
 
 package android.animation;
 
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.ConstantState;
 
 import java.util.ArrayList;
@@ -50,7 +51,7 @@
      * A set of flags which identify the type of configuration changes that can affect this
      * Animator. Used by the Animator cache.
      */
-    int mChangingConfigurations = 0;
+    @Config int mChangingConfigurations = 0;
 
     /**
      * If this animator is inflated from a constant state, keep a reference to it so that
@@ -344,7 +345,7 @@
      * @see android.content.pm.ActivityInfo
      * @hide
      */
-    public int getChangingConfigurations() {
+    public @Config int getChangingConfigurations() {
         return mChangingConfigurations;
     }
 
@@ -358,7 +359,7 @@
      * @see android.content.pm.ActivityInfo
      * @hide
      */
-    public void setChangingConfigurations(int configs) {
+    public void setChangingConfigurations(@Config int configs) {
         mChangingConfigurations = configs;
     }
 
@@ -368,7 +369,7 @@
      * This method is called while loading the animator.
      * @hide
      */
-    public void appendChangingConfigurations(int configs) {
+    public void appendChangingConfigurations(@Config int configs) {
         mChangingConfigurations |= configs;
     }
 
@@ -564,7 +565,7 @@
     private static class AnimatorConstantState extends ConstantState<Animator> {
 
         final Animator mAnimator;
-        int mChangingConf;
+        @Config int mChangingConf;
 
         public AnimatorConstantState(Animator animator) {
             mAnimator = animator;
@@ -574,7 +575,7 @@
         }
 
         @Override
-        public int getChangingConfigurations() {
+        public @Config int getChangingConfigurations() {
             return mChangingConf;
         }
 
diff --git a/core/java/android/animation/AnimatorInflater.java b/core/java/android/animation/AnimatorInflater.java
index 8d03b55..7d5931f 100644
--- a/core/java/android/animation/AnimatorInflater.java
+++ b/core/java/android/animation/AnimatorInflater.java
@@ -16,7 +16,10 @@
 package android.animation;
 
 import android.annotation.AnimatorRes;
+import android.annotation.AnyRes;
+import android.annotation.NonNull;
 import android.content.Context;
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.ConfigurationBoundResourceCache;
 import android.content.res.ConstantState;
 import android.content.res.Resources;
@@ -1062,7 +1065,7 @@
         return anim;
     }
 
-    private static int getChangingConfigs(Resources resources, int id) {
+    private static @Config int getChangingConfigs(@NonNull Resources resources, @AnyRes int id) {
         synchronized (sTmpTypedValue) {
             resources.getValue(id, sTmpTypedValue, true);
             return sTmpTypedValue.changingConfigurations;
diff --git a/core/java/android/animation/StateListAnimator.java b/core/java/android/animation/StateListAnimator.java
index d49e914..b6d6910 100644
--- a/core/java/android/animation/StateListAnimator.java
+++ b/core/java/android/animation/StateListAnimator.java
@@ -16,6 +16,7 @@
 
 package android.animation;
 
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.ConstantState;
 import android.util.StateSet;
 import android.view.View;
@@ -53,7 +54,7 @@
     private WeakReference<View> mViewRef;
     private StateListAnimatorConstantState mConstantState;
     private AnimatorListenerAdapter mAnimatorListener;
-    private int mChangingConfigurations;
+    private @Config int mChangingConfigurations;
 
     public StateListAnimator() {
         initAnimatorListener();
@@ -223,7 +224,7 @@
      * @see android.content.pm.ActivityInfo
      * @hide
      */
-    public int getChangingConfigurations() {
+    public @Config int getChangingConfigurations() {
         return mChangingConfigurations;
     }
 
@@ -237,7 +238,7 @@
      * @see android.content.pm.ActivityInfo
      * @hide
      */
-    public void setChangingConfigurations(int configs) {
+    public void setChangingConfigurations(@Config int configs) {
         mChangingConfigurations = configs;
     }
 
@@ -247,7 +248,7 @@
      * This method is called while loading the animator.
      * @hide
      */
-    public void appendChangingConfigurations(int configs) {
+    public void appendChangingConfigurations(@Config int configs) {
         mChangingConfigurations |= configs;
     }
 
@@ -309,7 +310,7 @@
 
         final StateListAnimator mAnimator;
 
-        int mChangingConf;
+        @Config int mChangingConf;
 
         public StateListAnimatorConstantState(StateListAnimator animator) {
             mAnimator = animator;
@@ -318,7 +319,7 @@
         }
 
         @Override
-        public int getChangingConfigurations() {
+        public @Config int getChangingConfigurations() {
             return mChangingConf;
         }
 
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 6b67b95..a0a599e 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1976,15 +1976,13 @@
      * normal {@link #onSaveInstanceState(Bundle)} mechanism) even if this
      * function returns null.
      *
-     * @return Returns the object previously returned by
-     * {@link #onRetainNonConfigurationInstance()}.
-     *
-     * @deprecated Use the new {@link Fragment} API
+     * <p><strong>Note:</strong> For most cases you should use the {@link Fragment} API
      * {@link Fragment#setRetainInstance(boolean)} instead; this is also
-     * available on older platforms through the Android compatibility package.
+     * available on older platforms through the Android support libraries.
+     *
+     * @return the object previously returned by {@link #onRetainNonConfigurationInstance()}
      */
     @Nullable
-    @Deprecated
     public Object getLastNonConfigurationInstance() {
         return mLastNonConfigurationInstances != null
                 ? mLastNonConfigurationInstances.activity : null;
@@ -2035,12 +2033,12 @@
      * guarantee for {@link android.os.AsyncTask#doInBackground} since that is
      * running in a separate thread.)
      *
-     * @return Return any Object holding the desired state to propagate to the
-     * next activity instance.
-     *
-     * @deprecated Use the new {@link Fragment} API
+     * <p><strong>Note:</strong> For most cases you should use the {@link Fragment} API
      * {@link Fragment#setRetainInstance(boolean)} instead; this is also
-     * available on older platforms through the Android compatibility package.
+     * available on older platforms through the Android support libraries.
+     *
+     * @return any Object holding the desired state to propagate to the
+     *         next activity instance
      */
     public Object onRetainNonConfigurationInstance() {
         return null;
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 8b62ef9..811a05b 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2307,7 +2307,7 @@
 
         case KEYGUARD_GOING_AWAY_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
-            keyguardGoingAway(data.readInt() != 0, data.readInt() != 0);
+            keyguardGoingAway(data.readInt());
             reply.writeNoException();
             return true;
         }
@@ -5924,13 +5924,12 @@
         reply.recycle();
     }
 
-    public void keyguardGoingAway(boolean disableWindowAnimations,
-            boolean keyguardGoingToNotificationShade) throws RemoteException {
+    public void keyguardGoingAway(int flags)
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(disableWindowAnimations ? 1 : 0);
-        data.writeInt(keyguardGoingToNotificationShade ? 1 : 0);
+        data.writeInt(flags);
         mRemote.transact(KEYGUARD_GOING_AWAY_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 094950b..f178455 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -777,15 +777,16 @@
 
     /**
      * Sets the bounds (window size) that the activity should be launched in.
+     * Rect position should be provided in pixels and in screen coordinates.
      * Set to null explicitly for fullscreen.
      * <p>
      * <strong>NOTE:<strong/> This value is ignored on devices that don't have
      * {@link android.content.pm.PackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT} or
      * {@link android.content.pm.PackageManager#FEATURE_PICTURE_IN_PICTURE} enabled.
-     * @param launchBounds Launch bounds to use for the activity or null for fullscreen.
+     * @param screenSpacePixelRect Launch bounds to use for the activity or null for fullscreen.
      */
-    public ActivityOptions setLaunchBounds(@Nullable Rect launchBounds) {
-        mLaunchBounds = launchBounds != null ? new Rect(launchBounds) : null;
+    public ActivityOptions setLaunchBounds(@Nullable Rect screenSpacePixelRect) {
+        mLaunchBounds = screenSpacePixelRect != null ? new Rect(screenSpacePixelRect) : null;
         return this;
     }
 
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index cdbf598..8e87e26 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -475,8 +475,13 @@
 
     public void keyguardWaitingForActivityDrawn() throws RemoteException;
 
-    public void keyguardGoingAway(boolean disableWindowAnimations,
-            boolean keyguardGoingToNotificationShade) throws RemoteException;
+    /**
+     * Notify the system that the keyguard is going away.
+     *
+     * @param flags See {@link android.view.WindowManagerPolicy#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE}
+     *              etc.
+     */
+    public void keyguardGoingAway(int flags) throws RemoteException;
 
     public boolean shouldUpRecreateTask(IBinder token, String destAffinity)
             throws RemoteException;
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index b8fc323..a03fd72 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -281,7 +281,7 @@
             addedPaths.addAll(newPaths);
         }
         synchronized (this) {
-            mClassLoader = createOrUpdateClassLoaderLocked(addedPaths);
+            createOrUpdateClassLoaderLocked(addedPaths);
             if (mResources != null) {
                 mResources = mActivityThread.getTopLevelResources(mResDir, mSplitResDirs,
                         mOverlayDirs, mApplicationInfo.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
@@ -402,101 +402,99 @@
                 }
             }
         }
-
-        final String zip = TextUtils.join(File.pathSeparator, outZipPaths);
     }
 
-    private ClassLoader createOrUpdateClassLoaderLocked(List<String> addedPaths) {
-        final ClassLoader classLoader;
-        if (mIncludeCode && !mPackageName.equals("android")) {
-            // Avoid the binder call when the package is the current application package.
-            // The activity manager will perform ensure that dexopt is performed before
-            // spinning up the process.
-            if (!Objects.equals(mPackageName, ActivityThread.currentPackageName())) {
-                VMRuntime.getRuntime().vmInstructionSet();
-                try {
-                    ActivityThread.getPackageManager().notifyPackageUse(mPackageName);
-                } catch (RemoteException re) {
-                    throw re.rethrowFromSystemServer();
-                }
+    private void createOrUpdateClassLoaderLocked(List<String> addedPaths) {
+        if (mPackageName.equals("android")) {
+            if (mClassLoader != null) {
+                // nothing to update
+                return;
             }
 
-            final List<String> zipPaths = new ArrayList<>();
-            final List<String> libPaths = new ArrayList<>();
-
-            if (mRegisterPackage) {
-                try {
-                    ActivityManagerNative.getDefault().addPackageDependency(mPackageName);
-                } catch (RemoteException e) {
-                    throw e.rethrowFromSystemServer();
-                }
-            }
-
-            makePaths(mActivityThread, mApplicationInfo, zipPaths, libPaths);
-            final String zip = TextUtils.join(File.pathSeparator, zipPaths);
-            final boolean isBundledApp = mApplicationInfo.isSystemApp()
-                    && !mApplicationInfo.isUpdatedSystemApp();
-            String libraryPermittedPath = mDataDir;
-            if (isBundledApp) {
-                // This is necessary to grant bundled apps access to
-                // libraries located in subdirectories of /system/lib
-                libraryPermittedPath += File.pathSeparator +
-                                        System.getProperty("java.library.path");
-            }
-            // DO NOT SHIP: this is a workaround for apps loading native libraries
-            // provided by 3rd party apps using absolute path instead of corresponding
-            // classloader; see http://b/26954419 for example.
-            if (mApplicationInfo.targetSdkVersion <= 23) {
-                libraryPermittedPath += File.pathSeparator + "/data/app";
-            }
-            // -----------------------------------------------------------------------------
-
-            final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
-
-            /*
-             * With all the combination done (if necessary, actually
-             * create the class loader.
-             */
-
-            if (ActivityThread.localLOGV)
-                Slog.v(ActivityThread.TAG, "Class path: " + zip +
-                        ", JNI path: " + librarySearchPath);
-
-            if (mClassLoader == null) {
-                // Temporarily disable logging of disk reads on the Looper thread
-                // as this is early and necessary.
-                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
-
-                classLoader = ApplicationLoaders.getDefault().getClassLoader(zip,
-                        mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
-                        libraryPermittedPath, mBaseClassLoader);
-
-                StrictMode.setThreadPolicy(oldPolicy);
-            } else if (addedPaths != null && addedPaths.size() > 0) {
-                final String add = TextUtils.join(File.pathSeparator, addedPaths);
-                ApplicationLoaders.getDefault().addPath(mClassLoader, add);
-                classLoader = mClassLoader;
+            if (mBaseClassLoader != null) {
+                mClassLoader = mBaseClassLoader;
             } else {
-                classLoader = mClassLoader;
+                mClassLoader = ClassLoader.getSystemClassLoader();
             }
-        } else {
-            if (mClassLoader == null) {
-                if (mBaseClassLoader == null) {
-                    classLoader = ClassLoader.getSystemClassLoader();
-                } else {
-                    classLoader = mBaseClassLoader;
-                }
-            } else {
-                classLoader = mClassLoader;
+
+            return;
+        }
+
+        // Avoid the binder call when the package is the current application package.
+        // The activity manager will perform ensure that dexopt is performed before
+        // spinning up the process.
+        if (!Objects.equals(mPackageName, ActivityThread.currentPackageName())) {
+            VMRuntime.getRuntime().vmInstructionSet();
+            try {
+                ActivityThread.getPackageManager().notifyPackageUse(mPackageName);
+            } catch (RemoteException re) {
+                throw re.rethrowFromSystemServer();
             }
         }
-        return classLoader;
+
+        final List<String> zipPaths = new ArrayList<>();
+        final List<String> libPaths = new ArrayList<>();
+
+        if (mRegisterPackage) {
+            try {
+                ActivityManagerNative.getDefault().addPackageDependency(mPackageName);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        makePaths(mActivityThread, mApplicationInfo, zipPaths, libPaths);
+        final String zip = mIncludeCode ? TextUtils.join(File.pathSeparator, zipPaths) : "";
+        final boolean isBundledApp = mApplicationInfo.isSystemApp()
+                && !mApplicationInfo.isUpdatedSystemApp();
+        String libraryPermittedPath = mDataDir;
+        if (isBundledApp) {
+            // This is necessary to grant bundled apps access to
+            // libraries located in subdirectories of /system/lib
+            libraryPermittedPath += File.pathSeparator +
+                                    System.getProperty("java.library.path");
+        }
+        // DO NOT SHIP: this is a workaround for apps loading native libraries
+        // provided by 3rd party apps using absolute path instead of corresponding
+        // classloader; see http://b/26954419 for example.
+        if (mApplicationInfo.targetSdkVersion <= 23) {
+            libraryPermittedPath += File.pathSeparator + "/data/app";
+        }
+        // -----------------------------------------------------------------------------
+
+        final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
+
+        /*
+         * With all the combination done (if necessary, actually
+         * create the class loader.
+         */
+
+        if (ActivityThread.localLOGV)
+            Slog.v(ActivityThread.TAG, "Class path: " + zip +
+                    ", JNI path: " + librarySearchPath);
+
+        if (mClassLoader == null) {
+            // Temporarily disable logging of disk reads on the Looper thread
+            // as this is early and necessary.
+            StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
+
+            mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip,
+                    mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
+                    libraryPermittedPath, mBaseClassLoader);
+
+            StrictMode.setThreadPolicy(oldPolicy);
+        }
+
+        if (addedPaths != null && addedPaths.size() > 0) {
+            final String add = TextUtils.join(File.pathSeparator, addedPaths);
+            ApplicationLoaders.getDefault().addPath(mClassLoader, add);
+        }
     }
 
     public ClassLoader getClassLoader() {
         synchronized (this) {
             if (mClassLoader == null) {
-                mClassLoader = createOrUpdateClassLoaderLocked(null /*addedPaths*/);
+                createOrUpdateClassLoaderLocked(null /*addedPaths*/);
             }
             return mClassLoader;
         }
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 2d06dcc..52e5272 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -919,8 +919,8 @@
      *     image for restore to a future device; {@code false} otherwise.
      * @param which Flags indicating which wallpaper(s) to configure with the new imagery.
      *
-     * @see #FLAG_SET_LOCK_WALLPAPER
-     * @see #FLAG_SET_SYSTEM_WALLPAPER
+     * @see #FLAG_SET_LOCK
+     * @see #FLAG_SET_SYSTEM
      *
      * @return An integer ID assigned to the newly active wallpaper; or zero on failure.
      *
@@ -1038,8 +1038,8 @@
      *     image for restore to a future device; {@code false} otherwise.
      * @param which Flags indicating which wallpaper(s) to configure with the new imagery.
      *
-     * @see #FLAG_SET_LOCK_WALLPAPER
-     * @see #FLAG_SET_SYSTEM_WALLPAPER
+     * @see #FLAG_SET_LOCK
+     * @see #FLAG_SET_SYSTEM
      *
      * @throws IOException
      */
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index a34e8551e..3be2cdc 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -284,10 +284,11 @@
     public static final String EXTRA_BUGREPORT_HASH = "android.app.extra.BUGREPORT_HASH";
 
     /**
-     * An {@code int} failure code representing the reason of the bugreport failure.
+     * An {@code int} failure code representing the reason of the bugreport failure. One of
+     * {@link #BUGREPORT_FAILURE_FAILED_COMPLETING}
+     * or {@link #BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE}
      *
      * @see #ACTION_BUGREPORT_FAILED
-     * @see #BUGREPORT_FAILURE_FAILED_COMPLETING, #BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE
      * @hide
      */
     public static final String EXTRA_BUGREPORT_FAILURE_REASON =
@@ -305,9 +306,24 @@
         BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE
     })
     public @interface BugreportFailureCode {}
-    /** Bugreport completion process failed. */
+
+    /**
+     * Bugreport completion process failed.
+     *
+     * <p>If this error code is received, the requesting of bugreport can be retried.
+     * @see DevicePolicyManager#requestBugreport
+     */
     public static final int BUGREPORT_FAILURE_FAILED_COMPLETING = 0;
-    /** Bugreport is no longer available for collection. */
+
+    /**
+     * Bugreport has been created, but is no longer available for collection.
+     *
+     * <p>This error likely occurs because the user of the device hasn't consented to share
+     * the bugreport for a long period after its creation.
+     *
+     * <p>If this error code is received, the requesting of bugreport can be retried.
+     * @see DevicePolicyManager#requestBugreport
+     */
     public static final int BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE = 1;
 
     /** @hide */
@@ -598,7 +614,8 @@
      * @param context The running context as per {@link #onReceive}.
      * @param intent The received intent as per {@link #onReceive}.
      * @param failureCode int containing failure code. One of
-     * #BUGREPORT_FAILURE_FAILED_COMPLETING or #BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE
+     * {@link #BUGREPORT_FAILURE_FAILED_COMPLETING}
+     * or {@link #BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE}
      * @see DevicePolicyManager#requestBugreport
      */
     public void onBugreportFailed(Context context, Intent intent,
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 53a6351..fd66954 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -25,16 +25,13 @@
 import android.annotation.SystemApi;
 import android.annotation.UserIdInt;
 import android.app.Activity;
-import android.auditing.SecurityLog;
 import android.auditing.SecurityLog.SecurityEvent;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
-import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.graphics.Bitmap;
 import android.net.ProxyInfo;
@@ -51,13 +48,12 @@
 import android.provider.Settings;
 import android.security.Credentials;
 import android.service.restrictions.RestrictionsReceiver;
+import android.telephony.TelephonyManager;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.org.conscrypt.TrustedCertificateStore;
 
-import org.xmlpull.v1.XmlPullParserException;
-
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.lang.annotation.Retention;
@@ -80,18 +76,18 @@
 
 /**
  * Public interface for managing policies enforced on a device. Most clients of this class must be
- * registered with the system as a
- * <a href="{@docRoot}guide/topics/admin/device-admin.html">device administrator</a>. Additionally,
- * a device administrator may be registered as either a profile or device owner. A given method is
- * accessible to all device administrators unless the documentation for that method specifies that
- * it is restricted to either device or profile owners.
- *
+ * registered with the system as a <a href="{@docRoot}guide/topics/admin/device-admin.html">device
+ * administrator</a>. Additionally, a device administrator may be registered as either a profile or
+ * device owner. A given method is accessible to all device administrators unless the documentation
+ * for that method specifies that it is restricted to either device or profile owners. Any
+ * application calling an api may only pass as an argument a device administrator component it
+ * owns. Otherwise, a {@link SecurityException} will be thrown.
  * <div class="special reference">
  * <h3>Developer Guides</h3>
- * <p>For more information about managing policies for device administration, read the
- * <a href="{@docRoot}guide/topics/admin/device-admin.html">Device Administration</a>
- * developer guide.
- * </div>
+ * <p>
+ * For more information about managing policies for device administration, read the <a href=
+ * "{@docRoot}guide/topics/admin/device-admin.html">Device Administration</a> developer
+ * guide. </div>
  */
 public class DevicePolicyManager {
     private static String TAG = "DevicePolicyManager";
@@ -1032,8 +1028,11 @@
     public @interface UserProvisioningState {}
 
     /**
-     * Return true if the given administrator component is currently
-     * active (enabled) in the system.
+     * Return true if the given administrator component is currently active (enabled) in the system.
+     *
+     * @param admin The administrator component to check for.
+     * @return {@code true} if {@code admin} is currently enabled in the system, {@code false}
+     *         otherwise
      */
     public boolean isAdminActive(@NonNull ComponentName admin) {
         return isAdminActiveAsUser(admin, myUserId());
@@ -1127,6 +1126,9 @@
      *
      * <p>Note that the operation is not synchronous and the admin might still be active (as
      * indicated by {@link #getActiveAdmins()}) by the time this method returns.
+     *
+     * @param admin The administration compononent to remove.
+     * @throws SecurityException if the caller is not in the owner application of {@code admin}.
      */
     public void removeActiveAdmin(@NonNull ComponentName admin) {
         if (mService != null) {
@@ -1139,13 +1141,14 @@
     }
 
     /**
-     * Returns true if an administrator has been granted a particular device policy.  This can
-     * be used to check whether the administrator was activated under an earlier set of policies,
-     * but requires additional policies after an upgrade.
+     * Returns true if an administrator has been granted a particular device policy. This can be
+     * used to check whether the administrator was activated under an earlier set of policies, but
+     * requires additional policies after an upgrade.
      *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.  Must be
-     * an active administrator, or an exception will be thrown.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Must be an
+     *            active administrator, or an exception will be thrown.
      * @param usesPolicy Which uses-policy to check, as defined in {@link DeviceAdminInfo}.
+     * @throws SecurityException if {@code admin} is not an active administrator.
      */
     public boolean hasGrantedPolicy(@NonNull ComponentName admin, int usesPolicy) {
         if (mService != null) {
@@ -1252,34 +1255,32 @@
     public static final int PASSWORD_QUALITY_MANAGED = 0x80000;
 
     /**
-     * Called by an application that is administering the device to set the
-     * password restrictions it is imposing.  After setting this, the user
-     * will not be able to enter a new password that is not at least as
-     * restrictive as what has been set.  Note that the current password
-     * will remain until the user has set a new one, so the change does not
-     * take place immediately.  To prompt the user for a new password, use
-     * {@link #ACTION_SET_NEW_PASSWORD} or
+     * Called by an application that is administering the device to set the password restrictions it
+     * is imposing. After setting this, the user will not be able to enter a new password that is
+     * not at least as restrictive as what has been set. Note that the current password will remain
+     * until the user has set a new one, so the change does not take place immediately. To prompt
+     * the user for a new password, use {@link #ACTION_SET_NEW_PASSWORD} or
      * {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after calling this method.
-     *
-     * <p>Quality constants are ordered so that higher values are more restrictive;
-     * thus the highest requested quality constant (between the policy set here,
-     * the user's preference, and any other considerations) is the one that
-     * is in effect.
-     *
-     * <p>The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
-     * this method; if it has not, a security exception will be thrown.
-     *
-     * <p>This method can be called on the {@link DevicePolicyManager} instance
-     * returned by {@link #getParentProfileInstance(ComponentName)} in order to set
-     * restrictions on the parent profile.
+     * <p>
+     * Quality constants are ordered so that higher values are more restrictive; thus the highest
+     * requested quality constant (between the policy set here, the user's preference, and any other
+     * considerations) is the one that is in effect.
+     * <p>
+     * The calling device admin must have requested
+     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call this method; if it has
+     * not, a security exception will be thrown.
+     * <p>
+     * This method can be called on the {@link DevicePolicyManager} instance returned by
+     * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent
+     * profile.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @param quality The new desired quality.  One of
-     * {@link #PASSWORD_QUALITY_UNSPECIFIED}, {@link #PASSWORD_QUALITY_SOMETHING},
-     * {@link #PASSWORD_QUALITY_NUMERIC}, {@link #PASSWORD_QUALITY_NUMERIC_COMPLEX},
-     * {@link #PASSWORD_QUALITY_ALPHABETIC}, {@link #PASSWORD_QUALITY_ALPHANUMERIC}
-     * or {@link #PASSWORD_QUALITY_COMPLEX}.
+     * @param quality The new desired quality. One of {@link #PASSWORD_QUALITY_UNSPECIFIED},
+     *            {@link #PASSWORD_QUALITY_SOMETHING}, {@link #PASSWORD_QUALITY_NUMERIC},
+     *            {@link #PASSWORD_QUALITY_NUMERIC_COMPLEX}, {@link #PASSWORD_QUALITY_ALPHABETIC},
+     *            {@link #PASSWORD_QUALITY_ALPHANUMERIC} or {@link #PASSWORD_QUALITY_COMPLEX}.
+     * @throws SecurityException if {@code admin} is not an active administrator or if {@code admin}
+     *             does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD}
      */
     public void setPasswordQuality(@NonNull ComponentName admin, int quality) {
         if (mService != null) {
@@ -1320,30 +1321,30 @@
     }
 
     /**
-     * Called by an application that is administering the device to set the
-     * minimum allowed password length.  After setting this, the user
-     * will not be able to enter a new password that is not at least as
-     * restrictive as what has been set.  Note that the current password
-     * will remain until the user has set a new one, so the change does not
-     * take place immediately.  To prompt the user for a new password, use
-     * {@link #ACTION_SET_NEW_PASSWORD}  or
-     * {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after setting this value.  This
-     * constraint is only imposed if the administrator has also requested either
-     * {@link #PASSWORD_QUALITY_NUMERIC}, {@link #PASSWORD_QUALITY_NUMERIC_COMPLEX},
-     * {@link #PASSWORD_QUALITY_ALPHABETIC}, {@link #PASSWORD_QUALITY_ALPHANUMERIC},
-     * or {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}.
-     *
-     * <p>The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
-     * this method; if it has not, a security exception will be thrown.
-     *
-     * <p>This method can be called on the {@link DevicePolicyManager} instance
-     * returned by {@link #getParentProfileInstance(ComponentName)} in order to set
-     * restrictions on the parent profile.
+     * Called by an application that is administering the device to set the minimum allowed password
+     * length. After setting this, the user will not be able to enter a new password that is not at
+     * least as restrictive as what has been set. Note that the current password will remain until
+     * the user has set a new one, so the change does not take place immediately. To prompt the user
+     * for a new password, use {@link #ACTION_SET_NEW_PASSWORD} or
+     * {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after setting this value. This constraint is
+     * only imposed if the administrator has also requested either {@link #PASSWORD_QUALITY_NUMERIC}
+     * , {@link #PASSWORD_QUALITY_NUMERIC_COMPLEX}, {@link #PASSWORD_QUALITY_ALPHABETIC},
+     * {@link #PASSWORD_QUALITY_ALPHANUMERIC}, or {@link #PASSWORD_QUALITY_COMPLEX} with
+     * {@link #setPasswordQuality}.
+     * <p>
+     * The calling device admin must have requested
+     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call this method; if it has
+     * not, a security exception will be thrown.
+     * <p>
+     * This method can be called on the {@link DevicePolicyManager} instance returned by
+     * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent
+     * profile.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @param length The new desired minimum password length.  A value of 0
-     * means there is no restriction.
+     * @param length The new desired minimum password length. A value of 0 means there is no
+     *            restriction.
+     * @throws SecurityException if {@code admin} is not an active administrator or {@code admin}
+     *             does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD}
      */
     public void setPasswordMinimumLength(@NonNull ComponentName admin, int length) {
         if (mService != null) {
@@ -1385,31 +1386,28 @@
     }
 
     /**
-     * Called by an application that is administering the device to set the
-     * minimum number of upper case letters required in the password. After
-     * setting this, the user will not be able to enter a new password that is
-     * not at least as restrictive as what has been set. Note that the current
-     * password will remain until the user has set a new one, so the change does
-     * not take place immediately. To prompt the user for a new password, use
-     * {@link #ACTION_SET_NEW_PASSWORD}  or
-     * {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after setting this value. This
-     * constraint is only imposed if the administrator has also requested
-     * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. The
-     * default value is 0.
+     * Called by an application that is administering the device to set the minimum number of upper
+     * case letters required in the password. After setting this, the user will not be able to enter
+     * a new password that is not at least as restrictive as what has been set. Note that the
+     * current password will remain until the user has set a new one, so the change does not take
+     * place immediately. To prompt the user for a new password, use
+     * {@link #ACTION_SET_NEW_PASSWORD} or {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after
+     * setting this value. This constraint is only imposed if the administrator has also requested
+     * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. The default value is 0.
      * <p>
      * The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
-     * this method; if it has not, a security exception will be thrown.
+     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call this method; if it has
+     * not, a security exception will be thrown.
+     * <p>
+     * This method can be called on the {@link DevicePolicyManager} instance returned by
+     * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent
+     * profile.
      *
-     * <p>This method can be called on the {@link DevicePolicyManager} instance
-     * returned by {@link #getParentProfileInstance(ComponentName)} in order to set
-     * restrictions on the parent profile.
-     *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated
-     *            with.
-     * @param length The new desired minimum number of upper case letters
-     *            required in the password. A value of 0 means there is no
-     *            restriction.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param length The new desired minimum number of upper case letters required in the password.
+     *            A value of 0 means there is no restriction.
+     * @throws SecurityException if {@code admin} is not an active administrator or {@code admin}
+     *             does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD}
      */
     public void setPasswordMinimumUpperCase(@NonNull ComponentName admin, int length) {
         if (mService != null) {
@@ -1457,31 +1455,28 @@
     }
 
     /**
-     * Called by an application that is administering the device to set the
-     * minimum number of lower case letters required in the password. After
-     * setting this, the user will not be able to enter a new password that is
-     * not at least as restrictive as what has been set. Note that the current
-     * password will remain until the user has set a new one, so the change does
-     * not take place immediately. To prompt the user for a new password, use
-     * {@link #ACTION_SET_NEW_PASSWORD} or
-     * {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after setting this value. This
-     * constraint is only imposed if the administrator has also requested
-     * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. The
-     * default value is 0.
+     * Called by an application that is administering the device to set the minimum number of lower
+     * case letters required in the password. After setting this, the user will not be able to enter
+     * a new password that is not at least as restrictive as what has been set. Note that the
+     * current password will remain until the user has set a new one, so the change does not take
+     * place immediately. To prompt the user for a new password, use
+     * {@link #ACTION_SET_NEW_PASSWORD} or {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after
+     * setting this value. This constraint is only imposed if the administrator has also requested
+     * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. The default value is 0.
      * <p>
      * The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
-     * this method; if it has not, a security exception will be thrown.
+     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call this method; if it has
+     * not, a security exception will be thrown.
+     * <p>
+     * This method can be called on the {@link DevicePolicyManager} instance returned by
+     * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent
+     * profile.
      *
-     * <p>This method can be called on the {@link DevicePolicyManager} instance
-     * returned by {@link #getParentProfileInstance(ComponentName)} in order to set
-     * restrictions on the parent profile.
-     *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated
-     *            with.
-     * @param length The new desired minimum number of lower case letters
-     *            required in the password. A value of 0 means there is no
-     *            restriction.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param length The new desired minimum number of lower case letters required in the password.
+     *            A value of 0 means there is no restriction.
+     * @throws SecurityException if {@code admin} is not an active administrator or {@code admin}
+     *             does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD}
      */
     public void setPasswordMinimumLowerCase(@NonNull ComponentName admin, int length) {
         if (mService != null) {
@@ -1529,30 +1524,28 @@
     }
 
     /**
-     * Called by an application that is administering the device to set the
-     * minimum number of letters required in the password. After setting this,
-     * the user will not be able to enter a new password that is not at least as
-     * restrictive as what has been set. Note that the current password will
-     * remain until the user has set a new one, so the change does not take
-     * place immediately. To prompt the user for a new password, use
-     * {@link #ACTION_SET_NEW_PASSWORD} or
-     * {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after setting this value. This
-     * constraint is only imposed if the administrator has also requested
-     * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. The
-     * default value is 1.
+     * Called by an application that is administering the device to set the minimum number of
+     * letters required in the password. After setting this, the user will not be able to enter a
+     * new password that is not at least as restrictive as what has been set. Note that the current
+     * password will remain until the user has set a new one, so the change does not take place
+     * immediately. To prompt the user for a new password, use {@link #ACTION_SET_NEW_PASSWORD} or
+     * {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after setting this value. This constraint is
+     * only imposed if the administrator has also requested {@link #PASSWORD_QUALITY_COMPLEX} with
+     * {@link #setPasswordQuality}. The default value is 1.
      * <p>
      * The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
-     * this method; if it has not, a security exception will be thrown.
+     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call this method; if it has
+     * not, a security exception will be thrown.
+     * <p>
+     * This method can be called on the {@link DevicePolicyManager} instance returned by
+     * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent
+     * profile.
      *
-     * <p>This method can be called on the {@link DevicePolicyManager} instance
-     * returned by {@link #getParentProfileInstance(ComponentName)} in order to set
-     * restrictions on the parent profile.
-     *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated
-     *            with.
-     * @param length The new desired minimum number of letters required in the
-     *            password. A value of 0 means there is no restriction.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param length The new desired minimum number of letters required in the password. A value of
+     *            0 means there is no restriction.
+     * @throws SecurityException if {@code admin} is not an active administrator or {@code admin}
+     *             does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD}
      */
     public void setPasswordMinimumLetters(@NonNull ComponentName admin, int length) {
         if (mService != null) {
@@ -1599,30 +1592,28 @@
     }
 
     /**
-     * Called by an application that is administering the device to set the
-     * minimum number of numerical digits required in the password. After
-     * setting this, the user will not be able to enter a new password that is
-     * not at least as restrictive as what has been set. Note that the current
-     * password will remain until the user has set a new one, so the change does
-     * not take place immediately. To prompt the user for a new password, use
-     * {@link #ACTION_SET_NEW_PASSWORD} or
-     * {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after setting this value. This
-     * constraint is only imposed if the administrator has also requested
-     * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. The
-     * default value is 1.
+     * Called by an application that is administering the device to set the minimum number of
+     * numerical digits required in the password. After setting this, the user will not be able to
+     * enter a new password that is not at least as restrictive as what has been set. Note that the
+     * current password will remain until the user has set a new one, so the change does not take
+     * place immediately. To prompt the user for a new password, use
+     * {@link #ACTION_SET_NEW_PASSWORD} or {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after
+     * setting this value. This constraint is only imposed if the administrator has also requested
+     * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. The default value is 1.
      * <p>
      * The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
-     * this method; if it has not, a security exception will be thrown.
+     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call this method; if it has
+     * not, a security exception will be thrown.
+     * <p>
+     * This method can be called on the {@link DevicePolicyManager} instance returned by
+     * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent
+     * profile.
      *
-     * <p>This method can be called on the {@link DevicePolicyManager} instance
-     * returned by {@link #getParentProfileInstance(ComponentName)} in order to set
-     * restrictions on the parent profile.
-     *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated
-     *            with.
-     * @param length The new desired minimum number of numerical digits required
-     *            in the password. A value of 0 means there is no restriction.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param length The new desired minimum number of numerical digits required in the password. A
+     *            value of 0 means there is no restriction.
+     * @throws SecurityException if {@code admin} is not an active administrator or {@code admin}
+     *             does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD}
      */
     public void setPasswordMinimumNumeric(@NonNull ComponentName admin, int length) {
         if (mService != null) {
@@ -1669,30 +1660,28 @@
     }
 
     /**
-     * Called by an application that is administering the device to set the
-     * minimum number of symbols required in the password. After setting this,
-     * the user will not be able to enter a new password that is not at least as
-     * restrictive as what has been set. Note that the current password will
-     * remain until the user has set a new one, so the change does not take
-     * place immediately. To prompt the user for a new password, use
-     * {@link #ACTION_SET_NEW_PASSWORD} or
-     * {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after setting this value. This
-     * constraint is only imposed if the administrator has also requested
-     * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. The
-     * default value is 1.
+     * Called by an application that is administering the device to set the minimum number of
+     * symbols required in the password. After setting this, the user will not be able to enter a
+     * new password that is not at least as restrictive as what has been set. Note that the current
+     * password will remain until the user has set a new one, so the change does not take place
+     * immediately. To prompt the user for a new password, use {@link #ACTION_SET_NEW_PASSWORD} or
+     * {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after setting this value. This constraint is
+     * only imposed if the administrator has also requested {@link #PASSWORD_QUALITY_COMPLEX} with
+     * {@link #setPasswordQuality}. The default value is 1.
      * <p>
      * The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
-     * this method; if it has not, a security exception will be thrown.
+     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call this method; if it has
+     * not, a security exception will be thrown.
+     * <p>
+     * This method can be called on the {@link DevicePolicyManager} instance returned by
+     * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent
+     * profile.
      *
-     * <p>This method can be called on the {@link DevicePolicyManager} instance
-     * returned by {@link #getParentProfileInstance(ComponentName)} in order to set
-     * restrictions on the parent profile.
-     *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated
-     *            with.
-     * @param length The new desired minimum number of symbols required in the
-     *            password. A value of 0 means there is no restriction.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param length The new desired minimum number of symbols required in the password. A value of
+     *            0 means there is no restriction.
+     * @throws SecurityException if {@code admin} is not an active administrator or {@code admin}
+     *             does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD}
      */
     public void setPasswordMinimumSymbols(@NonNull ComponentName admin, int length) {
         if (mService != null) {
@@ -1738,30 +1727,28 @@
     }
 
     /**
-     * Called by an application that is administering the device to set the
-     * minimum number of non-letter characters (numerical digits or symbols)
-     * required in the password. After setting this, the user will not be able
-     * to enter a new password that is not at least as restrictive as what has
-     * been set. Note that the current password will remain until the user has
-     * set a new one, so the change does not take place immediately. To prompt
-     * the user for a new password, use {@link #ACTION_SET_NEW_PASSWORD} or
-     * {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after
-     * setting this value. This constraint is only imposed if the administrator
-     * has also requested {@link #PASSWORD_QUALITY_COMPLEX} with
-     * {@link #setPasswordQuality}. The default value is 0.
+     * Called by an application that is administering the device to set the minimum number of
+     * non-letter characters (numerical digits or symbols) required in the password. After setting
+     * this, the user will not be able to enter a new password that is not at least as restrictive
+     * as what has been set. Note that the current password will remain until the user has set a new
+     * one, so the change does not take place immediately. To prompt the user for a new password,
+     * use {@link #ACTION_SET_NEW_PASSWORD} or {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after
+     * setting this value. This constraint is only imposed if the administrator has also requested
+     * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. The default value is 0.
      * <p>
      * The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
-     * this method; if it has not, a security exception will be thrown.
+     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call this method; if it has
+     * not, a security exception will be thrown.
+     * <p>
+     * This method can be called on the {@link DevicePolicyManager} instance returned by
+     * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent
+     * profile.
      *
-     * <p>This method can be called on the {@link DevicePolicyManager} instance
-     * returned by {@link #getParentProfileInstance(ComponentName)} in order to set
-     * restrictions on the parent profile.
-     *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated
-     *            with.
-     * @param length The new desired minimum number of letters required in the
-     *            password. A value of 0 means there is no restriction.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param length The new desired minimum number of letters required in the password. A value of
+     *            0 means there is no restriction.
+     * @throws SecurityException if {@code admin} is not an active administrator or {@code admin}
+     *             does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD}
      */
     public void setPasswordMinimumNonLetter(@NonNull ComponentName admin, int length) {
         if (mService != null) {
@@ -1807,33 +1794,31 @@
         return 0;
     }
 
-  /**
-   * Called by an application that is administering the device to set the length
-   * of the password history. After setting this, the user will not be able to
-   * enter a new password that is the same as any password in the history. Note
-   * that the current password will remain until the user has set a new one, so
-   * the change does not take place immediately. To prompt the user for a new
-   * password, use {@link #ACTION_SET_NEW_PASSWORD} or
-   * {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after setting this value.
-   * This constraint is only imposed if the administrator has also requested
-   * either {@link #PASSWORD_QUALITY_NUMERIC}, {@link #PASSWORD_QUALITY_NUMERIC_COMPLEX}
-   * {@link #PASSWORD_QUALITY_ALPHABETIC}, or {@link #PASSWORD_QUALITY_ALPHANUMERIC}
-   * with {@link #setPasswordQuality}.
-   *
-   * <p>
-   * The calling device admin must have requested
-   * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call this
-   * method; if it has not, a security exception will be thrown.
-   *
-   * <p>This method can be called on the {@link DevicePolicyManager} instance
-   * returned by {@link #getParentProfileInstance(ComponentName)} in order to set
-   * restrictions on the parent profile.
-   *
-   * @param admin Which {@link DeviceAdminReceiver} this request is associated
-   *        with.
-   * @param length The new desired length of password history. A value of 0
-   *        means there is no restriction.
-   */
+    /**
+     * Called by an application that is administering the device to set the length of the password
+     * history. After setting this, the user will not be able to enter a new password that is the
+     * same as any password in the history. Note that the current password will remain until the
+     * user has set a new one, so the change does not take place immediately. To prompt the user for
+     * a new password, use {@link #ACTION_SET_NEW_PASSWORD} or
+     * {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after setting this value. This constraint is
+     * only imposed if the administrator has also requested either {@link #PASSWORD_QUALITY_NUMERIC}
+     * , {@link #PASSWORD_QUALITY_NUMERIC_COMPLEX} {@link #PASSWORD_QUALITY_ALPHABETIC}, or
+     * {@link #PASSWORD_QUALITY_ALPHANUMERIC} with {@link #setPasswordQuality}.
+     * <p>
+     * The calling device admin must have requested
+     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call this method; if it has
+     * not, a security exception will be thrown.
+     * <p>
+     * This method can be called on the {@link DevicePolicyManager} instance returned by
+     * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent
+     * profile.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param length The new desired length of password history. A value of 0 means there is no
+     *            restriction.
+     * @throws SecurityException if {@code admin} is not an active administrator or {@code admin}
+     *             does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD}
+     */
     public void setPasswordHistoryLength(@NonNull ComponentName admin, int length) {
         if (mService != null) {
             try {
@@ -1845,30 +1830,32 @@
     }
 
     /**
-     * Called by a device admin to set the password expiration timeout. Calling this method
-     * will restart the countdown for password expiration for the given admin, as will changing
-     * the device password (for all admins).
-     *
-     * <p>The provided timeout is the time delta in ms and will be added to the current time.
-     * For example, to have the password expire 5 days from now, timeout would be
-     * 5 * 86400 * 1000 = 432000000 ms for timeout.
-     *
-     * <p>To disable password expiration, a value of 0 may be used for timeout.
-     *
-     * <p>The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_EXPIRE_PASSWORD} to be able to call this
-     * method; if it has not, a security exception will be thrown.
-     *
-     * <p> Note that setting the password will automatically reset the expiration time for all
-     * active admins. Active admins do not need to explicitly call this method in that case.
-     *
-     * <p>This method can be called on the {@link DevicePolicyManager} instance
-     * returned by {@link #getParentProfileInstance(ComponentName)} in order to set
-     * restrictions on the parent profile.
+     * Called by a device admin to set the password expiration timeout. Calling this method will
+     * restart the countdown for password expiration for the given admin, as will changing the
+     * device password (for all admins).
+     * <p>
+     * The provided timeout is the time delta in ms and will be added to the current time. For
+     * example, to have the password expire 5 days from now, timeout would be 5 * 86400 * 1000 =
+     * 432000000 ms for timeout.
+     * <p>
+     * To disable password expiration, a value of 0 may be used for timeout.
+     * <p>
+     * The calling device admin must have requested
+     * {@link DeviceAdminInfo#USES_POLICY_EXPIRE_PASSWORD} to be able to call this method; if it has
+     * not, a security exception will be thrown.
+     * <p>
+     * Note that setting the password will automatically reset the expiration time for all active
+     * admins. Active admins do not need to explicitly call this method in that case.
+     * <p>
+     * This method can be called on the {@link DevicePolicyManager} instance returned by
+     * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent
+     * profile.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @param timeout The limit (in ms) that a password can remain in effect. A value of 0
-     *        means there is no restriction (unlimited).
+     * @param timeout The limit (in ms) that a password can remain in effect. A value of 0 means
+     *            there is no restriction (unlimited).
+     * @throws SecurityException if {@code admin} is not an active administrator or {@code admin}
+     *             does not use {@link DeviceAdminInfo#USES_POLICY_EXPIRE_PASSWORD}
      */
     public void setPasswordExpirationTimeout(@NonNull ComponentName admin, long timeout) {
         if (mService != null) {
@@ -1970,20 +1957,22 @@
     }
 
     /**
-     * Determine whether the current password the user has set is sufficient
-     * to meet the policy requirements (e.g. quality, minimum length) that have been
-     * requested by the admins of this user and its participating profiles.
-     * Restrictions on profiles that have a separate challenge are not taken into account.
-     *
-     * <p>The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
-     * this method; if it has not, a security exception will be thrown.
-     *
-     * <p>This method can be called on the {@link DevicePolicyManager} instance
-     * returned by {@link #getParentProfileInstance(ComponentName)} in order to determine
-     * if the password set on the parent profile is sufficient.
+     * Determine whether the current password the user has set is sufficient to meet the policy
+     * requirements (e.g. quality, minimum length) that have been requested by the admins of this
+     * user and its participating profiles. Restrictions on profiles that have a separate challenge
+     * are not taken into account.
+     * <p>
+     * The calling device admin must have requested
+     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call this method; if it has
+     * not, a security exception will be thrown.
+     * <p>
+     * This method can be called on the {@link DevicePolicyManager} instance returned by
+     * {@link #getParentProfileInstance(ComponentName)} in order to determine if the password set on
+     * the parent profile is sufficient.
      *
      * @return Returns true if the password meets the current requirements, else false.
+     * @throws SecurityException if the calling application does not own an active administrator
+     *             that uses {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD}
      */
     public boolean isActivePasswordSufficient() {
         if (mService != null) {
@@ -2003,6 +1992,7 @@
      *
      * @param userHandle the userId of the profile to check the password for.
      * @return Returns true if the password would meet the current requirements, else false.
+     * @throws SecurityException if {@code userHandle} is not a managed profile.
      * @hide
      */
     public boolean isProfileActivePasswordSufficientForParent(int userHandle) {
@@ -2017,16 +2007,20 @@
     }
 
     /**
-     * Retrieve the number of times the user has failed at entering a
-     * password since that last successful password entry.
+     * Retrieve the number of times the user has failed at entering a password since that last
+     * successful password entry.
+     * <p>
+     * This method can be called on the {@link DevicePolicyManager} instance returned by
+     * {@link #getParentProfileInstance(ComponentName)} in order to retrieve the number of failed
+     * password attemts for the parent user.
+     * <p>
+     * The calling device admin must have requested {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN}
+     * to be able to call this method; if it has not, a security exception will be thrown.
      *
-     * <p>This method can be called on the {@link DevicePolicyManager} instance
-     * returned by {@link #getParentProfileInstance(ComponentName)} in order to retrieve
-     * the number of failed password attemts for the parent user.
-     *
-     * <p>The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to be able to call
-     * this method; if it has not, a security exception will be thrown.
+     * @return The number of times user has entered an incorrect password since the last correct
+     *         password entry.
+     * @throws SecurityException if the calling application does not own an active administrator
+     *             that uses {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN}
      */
     public int getCurrentFailedPasswordAttempts() {
         return getCurrentFailedPasswordAttempts(myUserId());
@@ -2071,27 +2065,28 @@
     }
 
     /**
-     * Setting this to a value greater than zero enables a built-in policy
-     * that will perform a device or profile wipe after too many incorrect
-     * device-unlock passwords have been entered.  This built-in policy combines
-     * watching for failed passwords and wiping the device, and requires
-     * that you request both {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} and
+     * Setting this to a value greater than zero enables a built-in policy that will perform a
+     * device or profile wipe after too many incorrect device-unlock passwords have been entered.
+     * This built-in policy combines watching for failed passwords and wiping the device, and
+     * requires that you request both {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} and
      * {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA}}.
-     *
-     * <p>To implement any other policy (e.g. wiping data for a particular
-     * application only, erasing or revoking credentials, or reporting the
-     * failure to a server), you should implement
-     * {@link DeviceAdminReceiver#onPasswordFailed(Context, android.content.Intent)}
-     * instead.  Do not use this API, because if the maximum count is reached,
-     * the device or profile will be wiped immediately, and your callback will not be invoked.
-     *
-     * <p>This method can be called on the {@link DevicePolicyManager} instance
-     * returned by {@link #getParentProfileInstance(ComponentName)} in order to set
-     * a value on the parent profile.
+     * <p>
+     * To implement any other policy (e.g. wiping data for a particular application only, erasing or
+     * revoking credentials, or reporting the failure to a server), you should implement
+     * {@link DeviceAdminReceiver#onPasswordFailed(Context, android.content.Intent)} instead. Do not
+     * use this API, because if the maximum count is reached, the device or profile will be wiped
+     * immediately, and your callback will not be invoked.
+     * <p>
+     * This method can be called on the {@link DevicePolicyManager} instance returned by
+     * {@link #getParentProfileInstance(ComponentName)} in order to set a value on the parent
+     * profile.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @param num The number of failed password attempts at which point the
-     * device or profile will be wiped.
+     * @param num The number of failed password attempts at which point the device or profile will
+     *            be wiped.
+     * @throws SecurityException if {@code admin} is not an active administrator or does not use
+     *             both {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} and
+     *             {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA}.
      */
     public void setMaximumFailedPasswordsForWipe(@NonNull ComponentName admin, int num) {
         if (mService != null) {
@@ -2169,42 +2164,41 @@
     public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 0x0002;
 
     /**
-     * Force a new device unlock password (the password needed to access the
-     * entire device, not for individual accounts) on the user.  This takes
-     * effect immediately.
-     *
-     * <p>Calling this from a managed profile that shares the password with the owner profile
-     * will throw a security exception.
-     *
-     * <p><em>Note: This API has been limited as of {@link android.os.Build.VERSION_CODES#N} for
+     * Force a new device unlock password (the password needed to access the entire device, not for
+     * individual accounts) on the user. This takes effect immediately.
+     * <p>
+     * Calling this from a managed profile that shares the password with the owner profile will
+     * throw a security exception.
+     * <p>
+     * <em>Note: This API has been limited as of {@link android.os.Build.VERSION_CODES#N} for
      * device admins that are not device owner and not profile owner.
      * The password can now only be changed if there is currently no password set.  Device owner
      * and profile owner can still do this.</em>
-     *
-     * <p>The given password must be sufficient for the
-     * current password quality and length constraints as returned by
-     * {@link #getPasswordQuality(ComponentName)} and
-     * {@link #getPasswordMinimumLength(ComponentName)}; if it does not meet
-     * these constraints, then it will be rejected and false returned.  Note
-     * that the password may be a stronger quality (containing alphanumeric
-     * characters when the requested quality is only numeric), in which case
-     * the currently active quality will be increased to match.
-     *
-     * <p>Calling with a null or empty password will clear any existing PIN,
-     * pattern or password if the current password constraints allow it. <em>Note: This will not
+     * <p>
+     * The given password must be sufficient for the current password quality and length constraints
+     * as returned by {@link #getPasswordQuality(ComponentName)} and
+     * {@link #getPasswordMinimumLength(ComponentName)}; if it does not meet these constraints, then
+     * it will be rejected and false returned. Note that the password may be a stronger quality
+     * (containing alphanumeric characters when the requested quality is only numeric), in which
+     * case the currently active quality will be increased to match.
+     * <p>
+     * Calling with a null or empty password will clear any existing PIN, pattern or password if the
+     * current password constraints allow it. <em>Note: This will not
      * work in {@link android.os.Build.VERSION_CODES#N} and later for device admins that are not
      * device owner and not profile owner.  Once set, the password cannot be changed to null or
      * empty, except by device owner or profile owner.</em>
-     *
-     * <p>The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_RESET_PASSWORD} to be able to call
-     * this method; if it has not, a security exception will be thrown.
+     * <p>
+     * The calling device admin must have requested
+     * {@link DeviceAdminInfo#USES_POLICY_RESET_PASSWORD} to be able to call this method; if it has
+     * not, a security exception will be thrown.
      *
      * @param password The new password for the user. Null or empty clears the password.
      * @param flags May be 0 or combination of {@link #RESET_PASSWORD_REQUIRE_ENTRY} and
-     *              {@link #RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT}.
-     * @return Returns true if the password was applied, or false if it is
-     * not acceptable for the current constraints or if the user has not been decrypted yet.
+     *            {@link #RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT}.
+     * @return Returns true if the password was applied, or false if it is not acceptable for the
+     *         current constraints or if the user has not been decrypted yet.
+     * @throws SecurityException if the calling application does not own an active administrator
+     *             that uses {@link DeviceAdminInfo#USES_POLICY_RESET_PASSWORD}
      */
     public boolean resetPassword(String password, int flags) {
         if (mParentInstance) {
@@ -2221,21 +2215,22 @@
     }
 
     /**
-     * Called by an application that is administering the device to set the
-     * maximum time for user activity until the device will lock.  This limits
-     * the length that the user can set.  It takes effect immediately.
-     *
-     * <p>The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK} to be able to call
-     * this method; if it has not, a security exception will be thrown.
-     *
-     * <p>This method can be called on the {@link DevicePolicyManager} instance
-     * returned by {@link #getParentProfileInstance(ComponentName)} in order to set
-     * restrictions on the parent profile.
+     * Called by an application that is administering the device to set the maximum time for user
+     * activity until the device will lock. This limits the length that the user can set. It takes
+     * effect immediately.
+     * <p>
+     * The calling device admin must have requested {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK}
+     * to be able to call this method; if it has not, a security exception will be thrown.
+     * <p>
+     * This method can be called on the {@link DevicePolicyManager} instance returned by
+     * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent
+     * profile.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @param timeMs The new desired maximum time to lock in milliseconds.
-     * A value of 0 means there is no restriction.
+     * @param timeMs The new desired maximum time to lock in milliseconds. A value of 0 means there
+     *            is no restriction.
+     * @throws SecurityException if {@code admin} is not an active administrator or it does not use
+     *             {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK}
      */
     public void setMaximumTimeToLock(@NonNull ComponentName admin, long timeMs) {
         if (mService != null) {
@@ -2278,16 +2273,17 @@
     }
 
     /**
-     * Make the device lock immediately, as if the lock screen timeout has
-     * expired at the point of this call.
+     * Make the device lock immediately, as if the lock screen timeout has expired at the point of
+     * this call.
+     * <p>
+     * The calling device admin must have requested {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK}
+     * to be able to call this method; if it has not, a security exception will be thrown.
+     * <p>
+     * This method can be called on the {@link DevicePolicyManager} instance returned by
+     * {@link #getParentProfileInstance(ComponentName)} in order to lock the parent profile.
      *
-     * <p>The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK} to be able to call
-     * this method; if it has not, a security exception will be thrown.
-     *
-     * <p>This method can be called on the {@link DevicePolicyManager} instance
-     * returned by {@link #getParentProfileInstance(ComponentName)} in order to lock
-     * the parent profile.
+     * @throws SecurityException if the calling application does not own an active administrator
+     *             that uses {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK}
      */
     public void lockNow() {
         if (mService != null) {
@@ -2315,16 +2311,16 @@
     public static final int WIPE_RESET_PROTECTION_DATA = 0x0002;
 
     /**
-     * Ask the user data be wiped.  Wiping the primary user will cause the
-     * device to reboot, erasing all user data while next booting up.
+     * Ask the user data be wiped. Wiping the primary user will cause the device to reboot, erasing
+     * all user data while next booting up.
+     * <p>
+     * The calling device admin must have requested {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA} to
+     * be able to call this method; if it has not, a security exception will be thrown.
      *
-     * <p>The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA} to be able to call
-     * this method; if it has not, a security exception will be thrown.
-     *
-     * @param flags Bit mask of additional options: currently supported flags
-     * are {@link #WIPE_EXTERNAL_STORAGE} and
-     * {@link #WIPE_RESET_PROTECTION_DATA}.
+     * @param flags Bit mask of additional options: currently supported flags are
+     *            {@link #WIPE_EXTERNAL_STORAGE} and {@link #WIPE_RESET_PROTECTION_DATA}.
+     * @throws SecurityException if the calling application does not own an active administrator
+     *             that uses {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA}
      */
     public void wipeData(int flags) {
         if (mService != null) {
@@ -2408,20 +2404,20 @@
     }
 
     /**
-     * Set a network-independent global HTTP proxy.  This is not normally what you want
-     * for typical HTTP proxies - they are generally network dependent.  However if you're
-     * doing something unusual like general internal filtering this may be useful.  On
-     * a private network where the proxy is not accessible, you may break HTTP using this.
+     * Set a network-independent global HTTP proxy. This is not normally what you want for typical
+     * HTTP proxies - they are generally network dependent. However if you're doing something
+     * unusual like general internal filtering this may be useful. On a private network where the
+     * proxy is not accessible, you may break HTTP using this.
+     * <p>
+     * This method requires the caller to be the device owner.
+     * <p>
+     * This proxy is only a recommendation and it is possible that some apps will ignore it.
      *
-     * <p>This method requires the caller to be the device owner.
-     *
-     * <p>This proxy is only a recommendation and it is possible that some apps will ignore it.
      * @see ProxyInfo
-     *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated
-     *            with.
-     * @param proxyInfo The a {@link ProxyInfo} object defining the new global
-     *        HTTP proxy.  A {@code null} value will clear the global HTTP proxy.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param proxyInfo The a {@link ProxyInfo} object defining the new global HTTP proxy. A
+     *            {@code null} value will clear the global HTTP proxy.
+     * @throws SecurityException if {@code admin} is not the device owner.
      */
     public void setRecommendedGlobalProxy(@NonNull ComponentName admin, @Nullable ProxyInfo
             proxyInfo) {
@@ -2487,6 +2483,12 @@
     public static final int ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY = 4;
 
     /**
+     * Result code for {@link #getStorageEncryptionStatus}:
+     * indicating that encryption is active and the encryption key is tied to the user.
+     */
+    public static final int ENCRYPTION_STATUS_ACTIVE_PER_USER = 5;
+
+    /**
      * Activity action: begin the process of encrypting data on the device.  This activity should
      * be launched after using {@link #setStorageEncryption} to request encryption be activated.
      * After resuming from this activity, use {@link #getStorageEncryption}
@@ -2538,36 +2540,35 @@
     public static final int KEYGUARD_DISABLE_FEATURES_ALL = 0x7fffffff;
 
     /**
-     * Called by an application that is administering the device to
-     * request that the storage system be encrypted.
-     *
-     * <p>When multiple device administrators attempt to control device
-     * encryption, the most secure, supported setting will always be
-     * used.  If any device administrator requests device encryption,
-     * it will be enabled;  Conversely, if a device administrator
-     * attempts to disable device encryption while another
-     * device administrator has enabled it, the call to disable will
+     * Called by an application that is administering the device to request that the storage system
+     * be encrypted.
+     * <p>
+     * When multiple device administrators attempt to control device encryption, the most secure,
+     * supported setting will always be used. If any device administrator requests device
+     * encryption, it will be enabled; Conversely, if a device administrator attempts to disable
+     * device encryption while another device administrator has enabled it, the call to disable will
      * fail (most commonly returning {@link #ENCRYPTION_STATUS_ACTIVE}).
-     *
-     * <p>This policy controls encryption of the secure (application data) storage area.  Data
-     * written to other storage areas may or may not be encrypted, and this policy does not require
-     * or control the encryption of any other storage areas.
-     * There is one exception:  If {@link android.os.Environment#isExternalStorageEmulated()} is
-     * {@code true}, then the directory returned by
-     * {@link android.os.Environment#getExternalStorageDirectory()} must be written to disk
-     * within the encrypted storage area.
-     *
-     * <p>Important Note:  On some devices, it is possible to encrypt storage without requiring
-     * the user to create a device PIN or Password.  In this case, the storage is encrypted, but
-     * the encryption key may not be fully secured.  For maximum security, the administrator should
-     * also require (and check for) a pattern, PIN, or password.
+     * <p>
+     * This policy controls encryption of the secure (application data) storage area. Data written
+     * to other storage areas may or may not be encrypted, and this policy does not require or
+     * control the encryption of any other storage areas. There is one exception: If
+     * {@link android.os.Environment#isExternalStorageEmulated()} is {@code true}, then the
+     * directory returned by {@link android.os.Environment#getExternalStorageDirectory()} must be
+     * written to disk within the encrypted storage area.
+     * <p>
+     * Important Note: On some devices, it is possible to encrypt storage without requiring the user
+     * to create a device PIN or Password. In this case, the storage is encrypted, but the
+     * encryption key may not be fully secured. For maximum security, the administrator should also
+     * require (and check for) a pattern, PIN, or password.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param encrypt true to request encryption, false to release any previous request
      * @return the new request status (for all active admins) - will be one of
-     * {@link #ENCRYPTION_STATUS_UNSUPPORTED}, {@link #ENCRYPTION_STATUS_INACTIVE}, or
-     * {@link #ENCRYPTION_STATUS_ACTIVE}.  This is the value of the requests;  Use
-     * {@link #getStorageEncryptionStatus()} to query the actual device state.
+     *         {@link #ENCRYPTION_STATUS_UNSUPPORTED}, {@link #ENCRYPTION_STATUS_INACTIVE}, or
+     *         {@link #ENCRYPTION_STATUS_ACTIVE}. This is the value of the requests; Use
+     *         {@link #getStorageEncryptionStatus()} to query the actual device state.
+     * @throws SecurityException if {@code admin} is not an active administrator or does not use
+     *             {@link DeviceAdminInfo#USES_ENCRYPTED_STORAGE}
      */
     public int setStorageEncryption(@NonNull ComponentName admin, boolean encrypt) {
         if (mService != null) {
@@ -2627,7 +2628,7 @@
     public int getStorageEncryptionStatus(int userHandle) {
         if (mService != null) {
             try {
-                return mService.getStorageEncryptionStatus(userHandle);
+                return mService.getStorageEncryptionStatus(mContext.getPackageName(), userHandle);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -2644,6 +2645,8 @@
      *
      * @return false if the certBuffer cannot be parsed or installation is
      *         interrupted, true otherwise.
+     * @throws SecurityException if {@code admin} is not {@code null} and not a device or profile
+     *         owner.
      */
     public boolean installCaCert(@Nullable ComponentName admin, byte[] certBuffer) {
         if (mService != null) {
@@ -2662,6 +2665,8 @@
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
      *              {@code null} if calling from a delegated certificate installer.
      * @param certBuffer encoded form of the certificate to remove.
+     * @throws SecurityException if {@code admin} is not {@code null} and not a device or profile
+     *         owner.
      */
     public void uninstallCaCert(@Nullable ComponentName admin, byte[] certBuffer) {
         if (mService != null) {
@@ -2684,6 +2689,8 @@
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
      *              {@code null} if calling from a delegated certificate installer.
      * @return a List of byte[] arrays, each encoding one user CA certificate.
+     * @throws SecurityException if {@code admin} is not {@code null} and not a device or profile
+     *         owner.
      */
     public List<byte[]> getInstalledCaCerts(@Nullable ComponentName admin) {
         List<byte[]> certs = new ArrayList<byte[]>();
@@ -2711,6 +2718,8 @@
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
      *              {@code null} if calling from a delegated certificate installer.
+     * @throws SecurityException if {@code admin} is not {@code null} and not a device or profile
+     *         owner.
      */
     public void uninstallAllUserCaCerts(@Nullable ComponentName admin) {
         if (mService != null) {
@@ -2729,6 +2738,8 @@
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
      *              {@code null} if calling from a delegated certificate installer.
      * @param certBuffer encoded form of the certificate to look up.
+     * @throws SecurityException if {@code admin} is not {@code null} and not a device or profile
+     *         owner.
      */
     public boolean hasCaCertInstalled(@Nullable ComponentName admin, byte[] certBuffer) {
         if (mService != null) {
@@ -2763,6 +2774,8 @@
      * @param alias The private key alias under which to install the certificate. If a certificate
      * with that alias already exists, it will be overwritten.
      * @return {@code true} if the keys were installed, {@code false} otherwise.
+     * @throws SecurityException if {@code admin} is not {@code null} and not a device or profile
+     *         owner.
      */
     public boolean installKeyPair(@Nullable ComponentName admin, @NonNull PrivateKey privKey,
             @NonNull Certificate cert, @NonNull String alias) {
@@ -2788,6 +2801,8 @@
      *        credentials immediately. Otherwise, access to the credentials will be gated by user
      *        approval.
      * @return {@code true} if the keys were installed, {@code false} otherwise.
+     * @throws SecurityException if {@code admin} is not {@code null} and not a device or profile
+     *         owner.
      */
     public boolean installKeyPair(@Nullable ComponentName admin, @NonNull PrivateKey privKey,
             @NonNull Certificate cert, @NonNull String alias, boolean requestAccess) {
@@ -2814,6 +2829,8 @@
      *        {@code null} if calling from a delegated certificate installer.
      * @param alias The private key alias under which the certificate is installed.
      * @return {@code true} if the private key alias no longer exists, {@code false} otherwise.
+     * @throws SecurityException if {@code admin} is not {@code null} and not a device or profile
+     *         owner.
      */
     public boolean removeKeyPair(@Nullable ComponentName admin, @NonNull String alias) {
         try {
@@ -2843,15 +2860,16 @@
      * Delegated certificate installer is a per-user state. The delegated access is persistent until
      * it is later cleared by calling this method with a null value or uninstallling the certificate
      * installer.
-     *<p>
+     * <p>
      * <b>Note:</b>Starting from {@link android.os.Build.VERSION_CODES#N}, if the caller
      * application's target SDK version is {@link android.os.Build.VERSION_CODES#N} or newer, the
-     * supplied certificate installer package must be installed when calling this API,
-     * otherwise an {@link IllegalArgumentException} will be thrown.
+     * supplied certificate installer package must be installed when calling this API, otherwise an
+     * {@link IllegalArgumentException} will be thrown.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param installerPackage The package name of the certificate installer which will be given
-     * access. If {@code null} is given the current package will be cleared.
+     *            access. If {@code null} is given the current package will be cleared.
+     * @throws SecurityException if {@code admin} is not a device or a profile owner.
      */
     public void setCertInstallerPackage(@NonNull ComponentName admin, @Nullable String
             installerPackage) throws SecurityException {
@@ -2865,12 +2883,13 @@
     }
 
     /**
-     * Called by a profile owner or device owner to retrieve the certificate installer for the
-     * user. null if none is set.
+     * Called by a profile owner or device owner to retrieve the certificate installer for the user.
+     * null if none is set.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @return The package name of the current delegated certificate installer, or {@code null}
-     * if none is set.
+     * @return The package name of the current delegated certificate installer, or {@code null} if
+     *         none is set.
+     * @throws SecurityException if {@code admin} is not a device or a profile owner.
      */
     public String getCertInstallerPackage(@NonNull ComponentName admin) throws SecurityException {
         if (mService != null) {
@@ -2885,18 +2904,18 @@
 
     /**
      * Called by a device or profile owner to configure an always-on VPN connection through a
-     * specific application for the current user.
-     * This connection is automatically granted and persisted after a reboot.
+     * specific application for the current user. This connection is automatically granted and
+     * persisted after a reboot.
+     * <p>
+     * The designated package should declare a {@link android.net.VpnService} in its manifest
+     * guarded by {@link android.Manifest.permission#BIND_VPN_SERVICE}, otherwise the call will
+     * fail.
      *
-     * <p>The designated package should declare a {@link android.net.VpnService} in its
-     *    manifest guarded by {@link android.Manifest.permission#BIND_VPN_SERVICE},
-     *    otherwise the call will fail.
-     *
-     * @param vpnPackage The package name for an installed VPN app on the device, or {@code null}
-     *                   to remove an existing always-on VPN configuration.
-     *
-     * @return {@code true} if the package is set as always-on VPN controller;
-     *         {@code false} otherwise.
+     * @param vpnPackage The package name for an installed VPN app on the device, or {@code null} to
+     *            remove an existing always-on VPN configuration.
+     * @return {@code true} if the package is set as always-on VPN controller; {@code false}
+     *         otherwise.
+     * @throws SecurityException if {@code admin} is not a device or a profile owner.
      */
     public boolean setAlwaysOnVpnPackage(@NonNull ComponentName admin,
             @Nullable String vpnPackage) {
@@ -2912,12 +2931,12 @@
 
     /**
      * Called by a device or profile owner to read the name of the package administering an
-     * always-on VPN connection for the current user.
-     * If there is no such package, or the always-on VPN is provided by the system instead
-     * of by an application, {@code null} will be returned.
+     * always-on VPN connection for the current user. If there is no such package, or the always-on
+     * VPN is provided by the system instead of by an application, {@code null} will be returned.
      *
-     * @return Package name of VPN controller responsible for always-on VPN,
-     *         or {@code null} if none is set.
+     * @return Package name of VPN controller responsible for always-on VPN, or {@code null} if none
+     *         is set.
+     * @throws SecurityException if {@code admin} is not a device or a profile owner.
      */
     public String getAlwaysOnVpnPackage(@NonNull ComponentName admin) {
         if (mService != null) {
@@ -2931,18 +2950,20 @@
     }
 
     /**
-     * Called by an application that is administering the device to disable all cameras
-     * on the device, for this user. After setting this, no applications running as this user
-     * will be able to access any cameras on the device.
-     *
-     * <p>If the caller is device owner, then the restriction will be applied to all users.
-     *
-     * <p>The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_DISABLE_CAMERA} to be able to call
-     * this method; if it has not, a security exception will be thrown.
+     * Called by an application that is administering the device to disable all cameras on the
+     * device, for this user. After setting this, no applications running as this user will be able
+     * to access any cameras on the device.
+     * <p>
+     * If the caller is device owner, then the restriction will be applied to all users.
+     * <p>
+     * The calling device admin must have requested
+     * {@link DeviceAdminInfo#USES_POLICY_DISABLE_CAMERA} to be able to call this method; if it has
+     * not, a security exception will be thrown.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param disabled Whether or not the camera should be disabled.
+     * @throws SecurityException if {@code admin} is not an active administrator or does not use
+     *             {@link DeviceAdminInfo#USES_POLICY_DISABLE_CAMERA}.
      */
     public void setCameraDisabled(@NonNull ComponentName admin, boolean disabled) {
         if (mService != null) {
@@ -2978,14 +2999,16 @@
 
     /**
      * Called by a device owner to request a bugreport.
-     *
-     * <p>There must be only one user on the device, managed by the device owner.
-     * Otherwise a {@link SecurityException} will be thrown.
+     * <p>
+     * There must be only one user on the device, managed by the device owner. Otherwise a
+     * {@link SecurityException} will be thrown.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @return {@code true} if the bugreport collection started successfully, or {@code false}
-     * if it wasn't triggered because a previous bugreport operation is still active
-     * (either the bugreport is still running or waiting for the user to share or decline)
+     * @return {@code true} if the bugreport collection started successfully, or {@code false} if it
+     *         wasn't triggered because a previous bugreport operation is still active (either the
+     *         bugreport is still running or waiting for the user to share or decline)
+     * @throws SecurityException if {@code admin} is not a device owner, or if there are users other
+     *             than the one managed by the device owner.
      */
     public boolean requestBugreport(@NonNull ComponentName admin) {
         if (mService != null) {
@@ -3014,15 +3037,16 @@
      * screen capture also prevents the content from being shown on display devices that do not have
      * a secure video output. See {@link android.view.Display#FLAG_SECURE} for more details about
      * secure surfaces and secure displays.
-     *
-     * <p>The calling device admin must be a device or profile owner. If it is not, a
-     * security exception will be thrown.
-     *
-     * <p>From version {@link android.os.Build.VERSION_CODES#M} disabling screen capture also
-     * blocks assist requests for all activities of the relevant user.
+     * <p>
+     * The calling device admin must be a device or profile owner. If it is not, a security
+     * exception will be thrown.
+     * <p>
+     * From version {@link android.os.Build.VERSION_CODES#M} disabling screen capture also blocks
+     * assist requests for all activities of the relevant user.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param disabled Whether screen capture is disabled or not.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void setScreenCaptureDisabled(@NonNull ComponentName admin, boolean disabled) {
         if (mService != null) {
@@ -3057,16 +3081,17 @@
     }
 
     /**
-     * Called by a device owner to set whether auto time is required. If auto time is
-     * required the user cannot set the date and time, but has to use network date and time.
-     *
-     * <p>Note: if auto time is required the user can still manually set the time zone.
-     *
-     * <p>The calling device admin must be a device owner. If it is not, a security exception will
-     * be thrown.
+     * Called by a device owner to set whether auto time is required. If auto time is required the
+     * user cannot set the date and time, but has to use network date and time.
+     * <p>
+     * Note: if auto time is required the user can still manually set the time zone.
+     * <p>
+     * The calling device admin must be a device owner. If it is not, a security exception will be
+     * thrown.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param required Whether auto time is set required or not.
+     * @throws SecurityException if {@code admin} is not a device owner.
      */
     public void setAutoTimeRequired(@NonNull ComponentName admin, boolean required) {
         if (mService != null) {
@@ -3094,15 +3119,16 @@
 
     /**
      * Called by a device owner to set whether all users created on the device should be ephemeral.
-     *
-     * <p>The system user is exempt from this policy - it is never ephemeral.
-     *
-     * <p>The calling device admin must be the device owner. If it is not, a security exception will
-     * be thrown.
+     * <p>
+     * The system user is exempt from this policy - it is never ephemeral.
+     * <p>
+     * The calling device admin must be the device owner. If it is not, a security exception will be
+     * thrown.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param forceEphemeralUsers If true, all the existing users will be deleted and all
-     *         subsequently created users will be ephemeral.
+     *            subsequently created users will be ephemeral.
+     * @throws SecurityException if {@code admin} is not a device owner.
      * @hide
      */
     public void setForceEphemeralUsers(
@@ -3118,6 +3144,7 @@
 
     /**
      * @return true if all users are created ephemeral.
+     * @throws SecurityException if {@code admin} is not a device owner.
      * @hide
      */
     public boolean getForceEphemeralUsers(@NonNull ComponentName admin) {
@@ -3135,39 +3162,41 @@
      * Called by an application that is administering the device to disable keyguard customizations,
      * such as widgets. After setting this, keyguard features will be disabled according to the
      * provided feature list.
-     *
-     * <p>The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} to be able to call
-     * this method; if it has not, a security exception will be thrown.
-     *
-     * <p>Calling this from a managed profile before version
-     * {@link android.os.Build.VERSION_CODES#M} will throw a security exception. From version
-     * {@link android.os.Build.VERSION_CODES#M} the profile owner of a managed profile can set:
+     * <p>
+     * The calling device admin must have requested
+     * {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} to be able to call this method;
+     * if it has not, a security exception will be thrown.
+     * <p>
+     * Calling this from a managed profile before version {@link android.os.Build.VERSION_CODES#M}
+     * will throw a security exception. From version {@link android.os.Build.VERSION_CODES#M} the
+     * profile owner of a managed profile can set:
      * <ul>
      * <li>{@link #KEYGUARD_DISABLE_TRUST_AGENTS}, which affects the parent user, but only if there
-     *      is no separate challenge set on the managed profile.
+     * is no separate challenge set on the managed profile.
      * <li>{@link #KEYGUARD_DISABLE_FINGERPRINT} which affects the managed profile challenge if
-     *      there is one, or the parent user otherwise.
-     * <li>{@link #KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS} which affects notifications
-     *      generated by applications in the managed profile.
+     * there is one, or the parent user otherwise.
+     * <li>{@link #KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS} which affects notifications generated
+     * by applications in the managed profile.
      * </ul>
-     *
      * {@link #KEYGUARD_DISABLE_TRUST_AGENTS} and {@link #KEYGUARD_DISABLE_FINGERPRINT} can also be
      * set on the {@link DevicePolicyManager} instance returned by
-     * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the
-     * parent profile.
-     *
-     * <p>Requests to disable other features on a managed profile will be ignored.
-     *
-     * <p>The admin can check which features have been disabled by calling
+     * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent
+     * profile.
+     * <p>
+     * Requests to disable other features on a managed profile will be ignored.
+     * <p>
+     * The admin can check which features have been disabled by calling
      * {@link #getKeyguardDisabledFeatures(ComponentName)}
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param which {@link #KEYGUARD_DISABLE_FEATURES_NONE} (default),
-     * {@link #KEYGUARD_DISABLE_WIDGETS_ALL}, {@link #KEYGUARD_DISABLE_SECURE_CAMERA},
-     * {@link #KEYGUARD_DISABLE_SECURE_NOTIFICATIONS}, {@link #KEYGUARD_DISABLE_TRUST_AGENTS},
-     * {@link #KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}, {@link #KEYGUARD_DISABLE_FINGERPRINT},
-     * {@link #KEYGUARD_DISABLE_FEATURES_ALL}
+     *            {@link #KEYGUARD_DISABLE_WIDGETS_ALL}, {@link #KEYGUARD_DISABLE_SECURE_CAMERA},
+     *            {@link #KEYGUARD_DISABLE_SECURE_NOTIFICATIONS},
+     *            {@link #KEYGUARD_DISABLE_TRUST_AGENTS},
+     *            {@link #KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS},
+     *            {@link #KEYGUARD_DISABLE_FINGERPRINT}, {@link #KEYGUARD_DISABLE_FEATURES_ALL}
+     * @throws SecurityException if {@code admin} is not an active administrator or does not user
+     *             {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES}
      */
     public void setKeyguardDisabledFeatures(@NonNull ComponentName admin, int which) {
         if (mService != null) {
@@ -3494,13 +3523,13 @@
     }
 
     /**
-     * Clears the current device owner.  The caller must be the device owner.
-     *
-     * This function should be used cautiously as once it is called it cannot
-     * be undone.  The device owner can only be set as a part of device setup
-     * before setup completes.
+     * Clears the current device owner. The caller must be the device owner. This function should be
+     * used cautiously as once it is called it cannot be undone. The device owner can only be set as
+     * a part of device setup before setup completes.
      *
      * @param packageName The package name of the device owner.
+     * @throws SecurityException if the caller is not in {@code packageName} or {@code packageName}
+     *             does not own the current device owner component.
      */
     public void clearDeviceOwnerApp(String packageName) {
         if (mService != null) {
@@ -3610,13 +3639,14 @@
     }
 
     /**
-     * Clears the active profile owner and removes all user restrictions. The caller must
-     * be from the same package as the active profile owner for this user, otherwise a
-     * SecurityException will be thrown.
-     *
-     * <p>This doesn't work for managed profile owners.
+     * Clears the active profile owner and removes all user restrictions. The caller must be from
+     * the same package as the active profile owner for this user, otherwise a SecurityException
+     * will be thrown.
+     * <p>
+     * This doesn't work for managed profile owners.
      *
      * @param admin The component to remove as the profile owner.
+     * @throws SecurityException if {@code admin} is not an active profile owner.
      */
     public void clearProfileOwner(@NonNull ComponentName admin) {
         if (mService != null) {
@@ -3676,20 +3706,21 @@
 
     /**
      * Sets the device owner information to be shown on the lock screen.
-     *
-     * <p>If the device owner information is {@code null} or empty then the device owner info is
+     * <p>
+     * If the device owner information is {@code null} or empty then the device owner info is
      * cleared and the user owner info is shown on the lock screen if it is set.
-     * <p>If the device owner information contains only whitespaces then the message on the lock
-     * screen will be blank and the user will not be allowed to change it.
-     *
-     * <p>If the device owner information needs to be localized, it is the responsibility of the
+     * <p>
+     * If the device owner information contains only whitespaces then the message on the lock screen
+     * will be blank and the user will not be allowed to change it.
+     * <p>
+     * If the device owner information needs to be localized, it is the responsibility of the
      * {@link DeviceAdminReceiver} to listen to the {@link Intent#ACTION_LOCALE_CHANGED} broadcast
      * and set a new version of this string accordingly.
      *
      * @param admin The name of the admin component to check.
-     * @param info Device owner information which will be displayed instead of the user
-     * owner info.
+     * @param info Device owner information which will be displayed instead of the user owner info.
      * @return Whether the device owner information has been set.
+     * @throws SecurityException if {@code admin} is not a device owner.
      */
     public boolean setDeviceOwnerLockScreenInfo(@NonNull ComponentName admin, String info) {
         if (mService != null) {
@@ -3718,21 +3749,22 @@
 
     /**
      * Called by device or profile owners to suspend packages for this user.
-     *
-     * <p>A suspended package will not be able to start activities. Its notifications will
-     * be hidden, it will not show up in recents, will not be able to show toasts or dialogs
-     * or ring the device.
-     *
-     * <p>The package must already be installed. If the package is uninstalled while suspended
-     * the package will no longer be suspended. The admin can block this by using
+     * <p>
+     * A suspended package will not be able to start activities. Its notifications will be hidden,
+     * it will not show up in recents, will not be able to show toasts or dialogs or ring the
+     * device.
+     * <p>
+     * The package must already be installed. If the package is uninstalled while suspended the
+     * package will no longer be suspended. The admin can block this by using
      * {@link #setUninstallBlocked}.
      *
      * @param admin The name of the admin component to check.
      * @param packageNames The package names to suspend or unsuspend.
      * @param suspended If set to {@code true} than the packages will be suspended, if set to
-     * {@code false} the packages will be unsuspended.
+     *            {@code false} the packages will be unsuspended.
      * @return an array of package names for which the suspended status is not set as requested in
-     * this method.
+     *         this method.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public String[] setPackagesSuspended(@NonNull ComponentName admin, String[] packageNames,
             boolean suspended) {
@@ -3752,7 +3784,8 @@
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param packageName The name of the package to retrieve the suspended status of.
      * @return {@code true} if the package is suspended or {@code false} if the package is not
-     * suspended, could not be found or an error occurred.
+     *         suspended, could not be found or an error occurred.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public boolean getPackageSuspended(@NonNull ComponentName admin, String packageName) {
         if (mService != null) {
@@ -3770,8 +3803,8 @@
      * be used. Only the profile owner can call this.
      *
      * @see #isProfileOwnerApp
-     *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @throws SecurityException if {@code admin} is not a profile owner.
      */
     public void setProfileEnabled(@NonNull ComponentName admin) {
         if (mService != null) {
@@ -3784,15 +3817,15 @@
     }
 
     /**
-     * Sets the name of the profile. In the device owner case it sets the name of the user
-     * which it is called from. Only a profile owner or device owner can call this. If this is
-     * never called by the profile or device owner, the name will be set to default values.
+     * Sets the name of the profile. In the device owner case it sets the name of the user which it
+     * is called from. Only a profile owner or device owner can call this. If this is never called
+     * by the profile or device owner, the name will be set to default values.
      *
      * @see #isProfileOwnerApp
      * @see #isDeviceOwnerApp
-     *
      * @param admin Which {@link DeviceAdminReceiver} this request is associate with.
      * @param profileName The name of the profile.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void setProfileName(@NonNull ComponentName admin, String profileName) {
         if (mService != null) {
@@ -3890,19 +3923,20 @@
     /**
      * Called by a profile owner or device owner to add a default intent handler activity for
      * intents that match a certain intent filter. This activity will remain the default intent
-     * handler even if the set of potential event handlers for the intent filter changes and if
-     * the intent preferences are reset.
-     *
-     * <p>The default disambiguation mechanism takes over if the activity is not installed
-     * (anymore). When the activity is (re)installed, it is automatically reset as default
-     * intent handler for the filter.
-     *
-     * <p>The calling device admin must be a profile owner or device owner. If it is not, a
-     * security exception will be thrown.
+     * handler even if the set of potential event handlers for the intent filter changes and if the
+     * intent preferences are reset.
+     * <p>
+     * The default disambiguation mechanism takes over if the activity is not installed (anymore).
+     * When the activity is (re)installed, it is automatically reset as default intent handler for
+     * the filter.
+     * <p>
+     * The calling device admin must be a profile owner or device owner. If it is not, a security
+     * exception will be thrown.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param filter The IntentFilter for which a default handler is added.
      * @param activity The Activity that is added as default intent handler.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void addPersistentPreferredActivity(@NonNull ComponentName admin, IntentFilter filter,
             @NonNull ComponentName activity) {
@@ -3918,12 +3952,13 @@
     /**
      * Called by a profile owner or device owner to remove all persistent intent handler preferences
      * associated with the given package that were set by {@link #addPersistentPreferredActivity}.
-     *
-     * <p>The calling device admin must be a profile owner. If it is not, a security
-     * exception will be thrown.
+     * <p>
+     * The calling device admin must be a profile owner. If it is not, a security exception will be
+     * thrown.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param packageName The name of the package for which preferences are removed.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void clearPackagePersistentPreferredActivities(@NonNull ComponentName admin,
             String packageName) {
@@ -3949,7 +3984,8 @@
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param packageName The package name which will be given access to application restrictions
-     * APIs. If {@code null} is given the current package will be cleared.
+     *            APIs. If {@code null} is given the current package will be cleared.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void setApplicationRestrictionsManagingPackage(@NonNull ComponentName admin,
             @Nullable String packageName) {
@@ -3968,7 +4004,8 @@
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @return The package name allowed to manage application restrictions on the current user, or
-     * {@code null} if none is set.
+     *         {@code null} if none is set.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public String getApplicationRestrictionsManagingPackage(@NonNull ComponentName admin) {
         if (mService != null) {
@@ -3999,34 +4036,34 @@
 
     /**
      * Sets the application restrictions for a given target application running in the calling user.
-     *
-     * <p>The caller must be a profile or device owner on that user, or the package allowed to
-     * manage application restrictions via {@link #setApplicationRestrictionsManagingPackage};
-     * otherwise a security exception will be thrown.
-     *
-     * <p>The provided {@link Bundle} consists of key-value pairs, where the types of values may be:
+     * <p>
+     * The caller must be a profile or device owner on that user, or the package allowed to manage
+     * application restrictions via {@link #setApplicationRestrictionsManagingPackage}; otherwise a
+     * security exception will be thrown.
+     * <p>
+     * The provided {@link Bundle} consists of key-value pairs, where the types of values may be:
      * <ul>
      * <li>{@code boolean}
      * <li>{@code int}
      * <li>{@code String} or {@code String[]}
      * <li>From {@link android.os.Build.VERSION_CODES#M}, {@code Bundle} or {@code Bundle[]}
      * </ul>
-     *
-     * <p>If the restrictions are not available yet, but may be applied in the near future,
-     * the caller can notify the target application of that by adding
+     * <p>
+     * If the restrictions are not available yet, but may be applied in the near future, the caller
+     * can notify the target application of that by adding
      * {@link UserManager#KEY_RESTRICTIONS_PENDING} to the settings parameter.
-     *
-     * <p>The application restrictions are only made visible to the target application via
-     * {@link UserManager#getApplicationRestrictions(String)}, in addition to the profile or
-     * device owner, and the application restrictions managing package via
+     * <p>
+     * The application restrictions are only made visible to the target application via
+     * {@link UserManager#getApplicationRestrictions(String)}, in addition to the profile or device
+     * owner, and the application restrictions managing package via
      * {@link #getApplicationRestrictions}.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
-     * {@code null} if called by the application restrictions managing package.
+     *            {@code null} if called by the application restrictions managing package.
      * @param packageName The name of the package to update restricted settings for.
      * @param settings A {@link Bundle} to be parsed by the receiving application, conveying a new
-     * set of active restrictions.
-     *
+     *            set of active restrictions.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      * @see #setApplicationRestrictionsManagingPackage
      * @see UserManager#KEY_RESTRICTIONS_PENDING
      */
@@ -4042,23 +4079,29 @@
     }
 
     /**
-     * Sets a list of configuration features to enable for a TrustAgent component. This is meant
-     * to be used in conjunction with {@link #KEYGUARD_DISABLE_TRUST_AGENTS}, which disables all
-     * trust agents but those enabled by this function call. If flag
+     * Sets a list of configuration features to enable for a TrustAgent component. This is meant to
+     * be used in conjunction with {@link #KEYGUARD_DISABLE_TRUST_AGENTS}, which disables all trust
+     * agents but those enabled by this function call. If flag
      * {@link #KEYGUARD_DISABLE_TRUST_AGENTS} is not set, then this call has no effect.
-     *
-     * <p>The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} to be able to call
-     * this method; if not, a security exception will be thrown.
+     * <p>
+     * The calling device admin must have requested
+     * {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} to be able to call this method;
+     * if not, a security exception will be thrown.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param target Component name of the agent to be enabled.
-     * @param configuration TrustAgent-specific feature bundle. If null for any admin, agent
-     * will be strictly disabled according to the state of the
-     *  {@link #KEYGUARD_DISABLE_TRUST_AGENTS} flag.
-     * <p>If {@link #KEYGUARD_DISABLE_TRUST_AGENTS} is set and options is not null for all admins,
-     * then it's up to the TrustAgent itself to aggregate the values from all device admins.
-     * <p>Consult documentation for the specific TrustAgent to determine legal options parameters.
+     * @param configuration TrustAgent-specific feature bundle. If null for any admin, agent will be
+     *            strictly disabled according to the state of the
+     *            {@link #KEYGUARD_DISABLE_TRUST_AGENTS} flag.
+     *            <p>
+     *            If {@link #KEYGUARD_DISABLE_TRUST_AGENTS} is set and options is not null for all
+     *            admins, then it's up to the TrustAgent itself to aggregate the values from all
+     *            device admins.
+     *            <p>
+     *            Consult documentation for the specific TrustAgent to determine legal options
+     *            parameters.
+     * @throws SecurityException if {@code admin} is not an active administrator or does not use
+     *             {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES}
      */
     public void setTrustAgentConfiguration(@NonNull ComponentName admin,
             @NonNull ComponentName target, PersistableBundle configuration) {
@@ -4104,14 +4147,15 @@
     }
 
     /**
-     * Called by a profile owner of a managed profile to set whether caller-Id information from
-     * the managed profile will be shown in the parent profile, for incoming calls.
-     *
-     * <p>The calling device admin must be a profile owner. If it is not, a
-     * security exception will be thrown.
+     * Called by a profile owner of a managed profile to set whether caller-Id information from the
+     * managed profile will be shown in the parent profile, for incoming calls.
+     * <p>
+     * The calling device admin must be a profile owner. If it is not, a security exception will be
+     * thrown.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param disabled If true caller-Id information in the managed profile is not displayed.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void setCrossProfileCallerIdDisabled(@NonNull ComponentName admin, boolean disabled) {
         if (mService != null) {
@@ -4126,11 +4170,12 @@
     /**
      * Called by a profile owner of a managed profile to determine whether or not caller-Id
      * information has been disabled.
-     *
-     * <p>The calling device admin must be a profile owner. If it is not, a
-     * security exception will be thrown.
+     * <p>
+     * The calling device admin must be a profile owner. If it is not, a security exception will be
+     * thrown.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public boolean getCrossProfileCallerIdDisabled(@NonNull ComponentName admin) {
         if (mService != null) {
@@ -4161,14 +4206,15 @@
     }
 
     /**
-     * Called by a profile owner of a managed profile to set whether contacts search from
-     * the managed profile will be shown in the parent profile, for incoming calls.
-     *
-     * <p>The calling device admin must be a profile owner. If it is not, a
-     * security exception will be thrown.
+     * Called by a profile owner of a managed profile to set whether contacts search from the
+     * managed profile will be shown in the parent profile, for incoming calls.
+     * <p>
+     * The calling device admin must be a profile owner. If it is not, a security exception will be
+     * thrown.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param disabled If true contacts search in the managed profile is not displayed.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void setCrossProfileContactsSearchDisabled(@NonNull ComponentName admin,
             boolean disabled) {
@@ -4184,11 +4230,12 @@
     /**
      * Called by a profile owner of a managed profile to determine whether or not contacts search
      * has been disabled.
-     *
-     * <p>The calling device admin must be a profile owner. If it is not, a
-     * security exception will be thrown.
+     * <p>
+     * The calling device admin must be a profile owner. If it is not, a security exception will be
+     * thrown.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public boolean getCrossProfileContactsSearchDisabled(@NonNull ComponentName admin) {
         if (mService != null) {
@@ -4248,18 +4295,17 @@
     }
 
     /**
-     * Called by a profile owner of a managed profile to set whether bluetooth
-     * devices can access enterprise contacts.
+     * Called by a profile owner of a managed profile to set whether bluetooth devices can access
+     * enterprise contacts.
      * <p>
-     * The calling device admin must be a profile owner. If it is not, a
-     * security exception will be thrown.
+     * The calling device admin must be a profile owner. If it is not, a security exception will be
+     * thrown.
      * <p>
      * This API works on managed profile only.
      *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated
-     *            with.
-     * @param disabled If true, bluetooth devices cannot access enterprise
-     *            contacts.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param disabled If true, bluetooth devices cannot access enterprise contacts.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void setBluetoothContactSharingDisabled(@NonNull ComponentName admin, boolean disabled) {
         if (mService != null) {
@@ -4272,16 +4318,16 @@
     }
 
     /**
-     * Called by a profile owner of a managed profile to determine whether or
-     * not Bluetooth devices cannot access enterprise contacts.
+     * Called by a profile owner of a managed profile to determine whether or not Bluetooth devices
+     * cannot access enterprise contacts.
      * <p>
-     * The calling device admin must be a profile owner. If it is not, a
-     * security exception will be thrown.
+     * The calling device admin must be a profile owner. If it is not, a security exception will be
+     * thrown.
      * <p>
      * This API works on managed profile only.
      *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated
-     *            with.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public boolean getBluetoothContactSharingDisabled(@NonNull ComponentName admin) {
         if (mService != null) {
@@ -4316,14 +4362,15 @@
 
     /**
      * Called by the profile owner of a managed profile so that some intents sent in the managed
-     * profile can also be resolved in the parent, or vice versa.
-     * Only activity intents are supported.
+     * profile can also be resolved in the parent, or vice versa. Only activity intents are
+     * supported.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param filter The {@link IntentFilter} the intent has to match to be also resolved in the
-     * other profile
+     *            other profile
      * @param flags {@link DevicePolicyManager#FLAG_MANAGED_CAN_ACCESS_PARENT} and
-     * {@link DevicePolicyManager#FLAG_PARENT_CAN_ACCESS_MANAGED} are supported.
+     *            {@link DevicePolicyManager#FLAG_PARENT_CAN_ACCESS_MANAGED} are supported.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void addCrossProfileIntentFilter(@NonNull ComponentName admin, IntentFilter filter, int flags) {
         if (mService != null) {
@@ -4339,7 +4386,9 @@
      * Called by a profile owner of a managed profile to remove the cross-profile intent filters
      * that go from the managed profile to the parent, or from the parent to the managed profile.
      * Only removes those that have been set by the profile owner.
+     *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void clearCrossProfileIntentFilters(@NonNull ComponentName admin) {
         if (mService != null) {
@@ -4352,25 +4401,22 @@
     }
 
     /**
-     * Called by a profile or device owner to set the permitted accessibility services. When
-     * set by a device owner or profile owner the restriction applies to all profiles of the
-     * user the device owner or profile owner is an admin for.
-     *
-     * By default the user can use any accessiblity service. When zero or more packages have
-     * been added, accessiblity services that are not in the list and not part of the system
-     * can not be enabled by the user.
-     *
-     * <p> Calling with a null value for the list disables the restriction so that all services
-     * can be used, calling with an empty list only allows the builtin system's services.
-     *
-     * <p> System accesibility services are always available to the user the list can't modify
-     * this.
+     * Called by a profile or device owner to set the permitted accessibility services. When set by
+     * a device owner or profile owner the restriction applies to all profiles of the user the
+     * device owner or profile owner is an admin for. By default the user can use any accessiblity
+     * service. When zero or more packages have been added, accessiblity services that are not in
+     * the list and not part of the system can not be enabled by the user.
+     * <p>
+     * Calling with a null value for the list disables the restriction so that all services can be
+     * used, calling with an empty list only allows the builtin system's services.
+     * <p>
+     * System accesibility services are always available to the user the list can't modify this.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param packageNames List of accessibility service package names.
-     *
-     * @return true if setting the restriction succeeded. It fail if there is
-     * one or more non-system accessibility services enabled, that are not in the list.
+     * @return true if setting the restriction succeeded. It fail if there is one or more non-system
+     *         accessibility services enabled, that are not in the list.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public boolean setPermittedAccessibilityServices(@NonNull ComponentName admin,
             List<String> packageNames) {
@@ -4386,12 +4432,13 @@
 
     /**
      * Returns the list of permitted accessibility services set by this device or profile owner.
-     *
-     * <p>An empty list means no accessibility services except system services are allowed.
-     * Null means all accessibility services are allowed.
+     * <p>
+     * An empty list means no accessibility services except system services are allowed. Null means
+     * all accessibility services are allowed.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @return List of accessiblity service package names.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public List<String> getPermittedAccessibilityServices(@NonNull ComponentName admin) {
         if (mService != null) {
@@ -4452,27 +4499,23 @@
      }
 
     /**
-     * Called by a profile or device owner to set the permitted input methods services. When
-     * set by a device owner or profile owner the restriction applies to all profiles of the
-     * user the device owner or profile owner is an admin for.
-     *
-     * By default the user can use any input method. When zero or more packages have
-     * been added, input method that are not in the list and not part of the system
-     * can not be enabled by the user.
-     *
-     * This method will fail if it is called for a admin that is not for the foreground user
-     * or a profile of the foreground user.
-     *
-     * <p> Calling with a null value for the list disables the restriction so that all input methods
-     * can be used, calling with an empty list disables all but the system's own input methods.
-     *
-     * <p> System input methods are always available to the user this method can't modify this.
+     * Called by a profile or device owner to set the permitted input methods services. When set by
+     * a device owner or profile owner the restriction applies to all profiles of the user the
+     * device owner or profile owner is an admin for. By default the user can use any input method.
+     * When zero or more packages have been added, input method that are not in the list and not
+     * part of the system can not be enabled by the user. This method will fail if it is called for
+     * a admin that is not for the foreground user or a profile of the foreground user.
+     * <p>
+     * Calling with a null value for the list disables the restriction so that all input methods can
+     * be used, calling with an empty list disables all but the system's own input methods.
+     * <p>
+     * System input methods are always available to the user this method can't modify this.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param packageNames List of input method package names.
-     * @return true if setting the restriction succeeded. It will fail if there are
-     *     one or more non-system input methods currently enabled that are not in
-     *     the packageNames list.
+     * @return true if setting the restriction succeeded. It will fail if there are one or more
+     *         non-system input methods currently enabled that are not in the packageNames list.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public boolean setPermittedInputMethods(@NonNull ComponentName admin, List<String> packageNames) {
         if (mService != null) {
@@ -4488,12 +4531,13 @@
 
     /**
      * Returns the list of permitted input methods set by this device or profile owner.
-     *
-     * <p>An empty list means no input methods except system input methods are allowed.
-     * Null means all input methods are allowed.
+     * <p>
+     * An empty list means no input methods except system input methods are allowed. Null means all
+     * input methods are allowed.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @return List of input method package names.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public List<String> getPermittedInputMethods(@NonNull ComponentName admin) {
         if (mService != null) {
@@ -4580,6 +4624,7 @@
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param packageNames List of package names to keep cached.
+     * @throws SecurityException if {@code admin} is not a device owner.
      * @hide
      */
     public void setKeepUninstalledPackages(@NonNull ComponentName admin,
@@ -4665,27 +4710,27 @@
      * persisted as user handles are recycled as users are removed and created. If you need to
      * persist an identifier for this user, use {@link UserManager#getSerialNumberForUser}. The new
      * user will not be started in the background.
-     *
-     * <p>admin is the {@link DeviceAdminReceiver} which is the device owner. profileOwner is also
-     * a DeviceAdminReceiver in the same package as admin, and will become the profile owner and
-     * will be registered as an active admin on the new user. The profile owner package will be
-     * installed on the new user.
-     *
-     * <p>If the adminExtras are not null, they will be stored on the device until the user is
-     * started for the first time. Then the extras will be passed to the admin when
-     * onEnable is called.
+     * <p>
+     * admin is the {@link DeviceAdminReceiver} which is the device owner. profileOwner is also a
+     * DeviceAdminReceiver in the same package as admin, and will become the profile owner and will
+     * be registered as an active admin on the new user. The profile owner package will be installed
+     * on the new user.
+     * <p>
+     * If the adminExtras are not null, they will be stored on the device until the user is started
+     * for the first time. Then the extras will be passed to the admin when onEnable is called.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param name The user's name.
      * @param profileOwner Which {@link DeviceAdminReceiver} will be profile owner. Has to be in the
-     *      same package as admin, otherwise no user is created and an IllegalArgumentException is
-     *      thrown.
+     *            same package as admin, otherwise no user is created and an
+     *            IllegalArgumentException is thrown.
      * @param adminExtras Extras that will be passed to onEnable of the admin receiver on the new
-     *      user.
+     *            user.
      * @param flags {@link #SKIP_SETUP_WIZARD} is supported.
      * @see UserHandle
      * @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
      *         user could not be created.
+     * @throws SecurityException if {@code admin} is not a device owner.
      */
     public UserHandle createAndManageUser(@NonNull ComponentName admin, @NonNull String name,
             @NonNull ComponentName profileOwner, @Nullable PersistableBundle adminExtras,
@@ -4698,12 +4743,13 @@
     }
 
     /**
-     * Called by a device owner to remove a user and all associated data. The primary user can
-     * not be removed.
+     * Called by a device owner to remove a user and all associated data. The primary user can not
+     * be removed.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param userHandle the user to remove.
      * @return {@code true} if the user was removed, {@code false} otherwise.
+     * @throws SecurityException if {@code admin} is not a device owner.
      */
     public boolean removeUser(@NonNull ComponentName admin, UserHandle userHandle) {
         try {
@@ -4719,7 +4765,7 @@
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param userHandle the user to switch to; null will switch to primary.
      * @return {@code true} if the switch was successful, {@code false} otherwise.
-     *
+     * @throws SecurityException if {@code admin} is not a device owner.
      * @see Intent#ACTION_USER_FOREGROUND
      */
     public boolean switchUser(@NonNull ComponentName admin, @Nullable UserHandle userHandle) {
@@ -4733,18 +4779,18 @@
     /**
      * Retrieves the application restrictions for a given target application running in the calling
      * user.
-     *
-     * <p>The caller must be a profile or device owner on that user, or the package allowed to
-     * manage application restrictions via {@link #setApplicationRestrictionsManagingPackage};
-     * otherwise a security exception will be thrown.
+     * <p>
+     * The caller must be a profile or device owner on that user, or the package allowed to manage
+     * application restrictions via {@link #setApplicationRestrictionsManagingPackage}; otherwise a
+     * security exception will be thrown.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
-     * {@code null} if called by the application restrictions managing package.
+     *            {@code null} if called by the application restrictions managing package.
      * @param packageName The name of the package to fetch restricted settings of.
      * @return {@link Bundle} of settings corresponding to what was set last time
-     * {@link DevicePolicyManager#setApplicationRestrictions} was called, or an empty {@link Bundle}
-     * if no restrictions have been set.
-     *
+     *         {@link DevicePolicyManager#setApplicationRestrictions} was called, or an empty
+     *         {@link Bundle} if no restrictions have been set.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      * @see {@link #setApplicationRestrictionsManagingPackage}
      */
     public Bundle getApplicationRestrictions(@Nullable ComponentName admin, String packageName) {
@@ -4761,13 +4807,13 @@
     /**
      * Called by a profile or device owner to set a user restriction specified by the key.
      * <p>
-     * The calling device admin must be a profile or device owner; if it is not,
-     * a security exception will be thrown.
+     * The calling device admin must be a profile or device owner; if it is not, a security
+     * exception will be thrown.
      *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated
-     *            with.
-     * @param key The key of the restriction. See the constants in
-     *            {@link android.os.UserManager} for the list of keys.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param key The key of the restriction. See the constants in {@link android.os.UserManager}
+     *            for the list of keys.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void addUserRestriction(@NonNull ComponentName admin, String key) {
         if (mService != null) {
@@ -4782,13 +4828,13 @@
     /**
      * Called by a profile or device owner to clear a user restriction specified by the key.
      * <p>
-     * The calling device admin must be a profile or device owner; if it is not,
-     * a security exception will be thrown.
+     * The calling device admin must be a profile or device owner; if it is not, a security
+     * exception will be thrown.
      *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated
-     *            with.
-     * @param key The key of the restriction. See the constants in
-     *            {@link android.os.UserManager} for the list of keys.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param key The key of the restriction. See the constants in {@link android.os.UserManager}
+     *            for the list of keys.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void clearUserRestriction(@NonNull ComponentName admin, String key) {
         if (mService != null) {
@@ -4805,11 +4851,11 @@
      * {@link #addUserRestriction(ComponentName, String)}.
      * <p>
      * The target user may have more restrictions set by the system or other device owner / profile
-     * owner.  To get all the user restrictions currently set, use
+     * owner. To get all the user restrictions currently set, use
      * {@link UserManager#getUserRestrictions()}.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @throws SecurityException if the {@code admin} is not an active admin.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public Bundle getUserRestrictions(@NonNull ComponentName admin) {
         return getUserRestrictions(admin, myUserId());
@@ -4829,14 +4875,15 @@
     }
 
     /**
-     * Called by profile or device owners to hide or unhide packages. When a package is hidden it
-     * is unavailable for use, but the data and actual package file remain.
+     * Called by profile or device owners to hide or unhide packages. When a package is hidden it is
+     * unavailable for use, but the data and actual package file remain.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param packageName The name of the package to hide or unhide.
      * @param hidden {@code true} if the package should be hidden, {@code false} if it should be
-     *                 unhidden.
+     *            unhidden.
      * @return boolean Whether the hidden setting of the package was successfully updated.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public boolean setApplicationHidden(@NonNull ComponentName admin, String packageName,
             boolean hidden) {
@@ -4856,6 +4903,7 @@
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param packageName The name of the package to retrieve the hidden status of.
      * @return boolean {@code true} if the package is hidden, {@code false} otherwise.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public boolean isApplicationHidden(@NonNull ComponentName admin, String packageName) {
         if (mService != null) {
@@ -4874,6 +4922,7 @@
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param packageName The package to be re-enabled in the calling profile.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void enableSystemApp(@NonNull ComponentName admin, String packageName) {
         if (mService != null) {
@@ -4886,13 +4935,14 @@
     }
 
     /**
-     * Called by profile or device owners to re-enable system apps by intent that were disabled
-     * by default when the user was initialized.
+     * Called by profile or device owners to re-enable system apps by intent that were disabled by
+     * default when the user was initialized.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param intent An intent matching the app(s) to be installed. All apps that resolve for this
-     *               intent will be re-enabled in the calling profile.
+     *            intent will be re-enabled in the calling profile.
      * @return int The number of activities that matched the intent and were installed.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public int enableSystemApp(@NonNull ComponentName admin, Intent intent) {
         if (mService != null) {
@@ -4908,21 +4958,22 @@
     /**
      * Called by a device owner or profile owner to disable account management for a specific type
      * of account.
-     *
-     * <p>The calling device admin must be a device owner or profile owner. If it is not, a
-     * security exception will be thrown.
-     *
-     * <p>When account management is disabled for an account type, adding or removing an account
-     * of that type will not be possible.
-     *
-     * <p>From {@link android.os.Build.VERSION_CODES#N} the profile or device owner can still use
+     * <p>
+     * The calling device admin must be a device owner or profile owner. If it is not, a security
+     * exception will be thrown.
+     * <p>
+     * When account management is disabled for an account type, adding or removing an account of
+     * that type will not be possible.
+     * <p>
+     * From {@link android.os.Build.VERSION_CODES#N} the profile or device owner can still use
      * {@link android.accounts.AccountManager} APIs to add or remove accounts when account
      * management for a specific type is disabled.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param accountType For which account management is disabled or enabled.
      * @param disabled The boolean indicating that account management will be disabled (true) or
-     * enabled (false).
+     *            enabled (false).
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void setAccountManagementDisabled(@NonNull ComponentName admin, String accountType,
             boolean disabled) {
@@ -4967,17 +5018,15 @@
 
     /**
      * Sets which packages may enter lock task mode.
+     * <p>
+     * Any packages that shares uid with an allowed package will also be allowed to activate lock
+     * task. From {@link android.os.Build.VERSION_CODES#M} removing packages from the lock task
+     * package list results in locked tasks belonging to those packages to be finished. This
+     * function can only be called by the device owner.
      *
-     * <p>Any packages that shares uid with an allowed package will also be allowed
-     * to activate lock task.
-     *
-     * From {@link android.os.Build.VERSION_CODES#M} removing packages from the lock task
-     * package list results in locked tasks belonging to those packages to be finished.
-     *
-     * This function can only be called by the device owner.
      * @param packages The list of packages allowed to enter lock task mode
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     *
+     * @throws SecurityException if {@code admin} is not a device owner.
      * @see Activity#startLockTask()
      * @see DeviceAdminReceiver#onLockTaskModeEntering(Context, Intent, String)
      * @see DeviceAdminReceiver#onLockTaskModeExiting(Context, Intent)
@@ -5030,7 +5079,8 @@
     /**
      * Called by device owners to update {@link Settings.Global} settings. Validation that the value
      * of the setting is in the correct form for the setting type should be performed by the caller.
-     * <p>The settings that can be updated with this method are:
+     * <p>
+     * The settings that can be updated with this method are:
      * <ul>
      * <li>{@link Settings.Global#ADB_ENABLED}</li>
      * <li>{@link Settings.Global#AUTO_TIME}</li>
@@ -5038,30 +5088,30 @@
      * <li>{@link Settings.Global#DATA_ROAMING}</li>
      * <li>{@link Settings.Global#USB_MASS_STORAGE_ENABLED}</li>
      * <li>{@link Settings.Global#WIFI_SLEEP_POLICY}</li>
-     * <li>{@link Settings.Global#STAY_ON_WHILE_PLUGGED_IN}
-     *   This setting is only available from {@link android.os.Build.VERSION_CODES#M} onwards
-     *   and can only be set if {@link #setMaximumTimeToLock} is not used to set a timeout.</li>
-     * <li>{@link Settings.Global#WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN}</li>
-     *   This setting is only available from {@link android.os.Build.VERSION_CODES#M} onwards.
-     *   </li>
+     * <li>{@link Settings.Global#STAY_ON_WHILE_PLUGGED_IN} This setting is only available from
+     * {@link android.os.Build.VERSION_CODES#M} onwards and can only be set if
+     * {@link #setMaximumTimeToLock} is not used to set a timeout.</li>
+     * <li>{@link Settings.Global#WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN}</li> This setting is only
+     * available from {@link android.os.Build.VERSION_CODES#M} onwards.</li>
      * </ul>
-     * <p>Changing the following settings has no effect as of
-     * {@link android.os.Build.VERSION_CODES#M}:
+     * <p>
+     * Changing the following settings has no effect as of {@link android.os.Build.VERSION_CODES#M}:
      * <ul>
-     * <li>{@link Settings.Global#BLUETOOTH_ON}.
-     *   Use {@link android.bluetooth.BluetoothAdapter#enable()} and
-     *   {@link android.bluetooth.BluetoothAdapter#disable()} instead.</li>
+     * <li>{@link Settings.Global#BLUETOOTH_ON}. Use
+     * {@link android.bluetooth.BluetoothAdapter#enable()} and
+     * {@link android.bluetooth.BluetoothAdapter#disable()} instead.</li>
      * <li>{@link Settings.Global#DEVELOPMENT_SETTINGS_ENABLED}</li>
-     * <li>{@link Settings.Global#MODE_RINGER}.
-     *   Use {@link android.media.AudioManager#setRingerMode(int)} instead.</li>
+     * <li>{@link Settings.Global#MODE_RINGER}. Use
+     * {@link android.media.AudioManager#setRingerMode(int)} instead.</li>
      * <li>{@link Settings.Global#NETWORK_PREFERENCE}</li>
-     * <li>{@link Settings.Global#WIFI_ON}.
-     *   Use {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)} instead.</li>
+     * <li>{@link Settings.Global#WIFI_ON}. Use
+     * {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)} instead.</li>
      * </ul>
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param setting The name of the setting to update.
      * @param value The value to update the setting to.
+     * @throws SecurityException if {@code admin} is not a device owner.
      */
     public void setGlobalSetting(@NonNull ComponentName admin, String setting, String value) {
         if (mService != null) {
@@ -5077,19 +5127,23 @@
      * Called by profile or device owners to update {@link Settings.Secure} settings. Validation
      * that the value of the setting is in the correct form for the setting type should be performed
      * by the caller.
-     * <p>The settings that can be updated by a profile or device owner with this method are:
+     * <p>
+     * The settings that can be updated by a profile or device owner with this method are:
      * <ul>
      * <li>{@link Settings.Secure#DEFAULT_INPUT_METHOD}</li>
      * <li>{@link Settings.Secure#INSTALL_NON_MARKET_APPS}</li>
      * <li>{@link Settings.Secure#SKIP_FIRST_USE_HINTS}</li>
      * </ul>
-     * <p>A device owner can additionally update the following settings:
+     * <p>
+     * A device owner can additionally update the following settings:
      * <ul>
      * <li>{@link Settings.Secure#LOCATION_MODE}</li>
      * </ul>
+     *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param setting The name of the setting to update.
      * @param value The value to update the setting to.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void setSecureSetting(@NonNull ComponentName admin, String setting, String value) {
         if (mService != null) {
@@ -5102,14 +5156,16 @@
     }
 
     /**
-     * Designates a specific service component as the provider for
-     * making permission requests of a local or remote administrator of the user.
+     * Designates a specific service component as the provider for making permission requests of a
+     * local or remote administrator of the user.
      * <p/>
      * Only a profile owner can designate the restrictions provider.
+     *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param provider The component name of the service that implements
-     * {@link RestrictionsReceiver}. If this param is null,
-     * it removes the restrictions provider previously assigned.
+     *            {@link RestrictionsReceiver}. If this param is null, it removes the restrictions
+     *            provider previously assigned.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void setRestrictionsProvider(@NonNull ComponentName admin,
             @Nullable ComponentName provider) {
@@ -5127,6 +5183,7 @@
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param on {@code true} to mute master volume, {@code false} to turn mute off.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void setMasterVolumeMuted(@NonNull ComponentName admin, boolean on) {
         if (mService != null) {
@@ -5143,6 +5200,7 @@
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @return {@code true} if master volume is muted, {@code false} if it's not.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public boolean isMasterVolumeMuted(@NonNull ComponentName admin) {
         if (mService != null) {
@@ -5156,12 +5214,12 @@
     }
 
     /**
-     * Called by profile or device owners to change whether a user can uninstall
-     * a package.
+     * Called by profile or device owners to change whether a user can uninstall a package.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param packageName package to change.
      * @param uninstallBlocked true if the user shouldn't be able to uninstall the package.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void setUninstallBlocked(@NonNull ComponentName admin, String packageName,
             boolean uninstallBlocked) {
@@ -5179,14 +5237,15 @@
      * Requires the caller to be the profile owner if checking a specific admin's policy.
      * <p>
      * <strong>Note:</strong> Starting from {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1}, the
-     * behavior of this API is changed such that passing {@code null} as the {@code admin}
-     * parameter will return if any admin has blocked the uninstallation. Before L MR1, passing
-     * {@code null} will cause a NullPointerException to be raised.
+     * behavior of this API is changed such that passing {@code null} as the {@code admin} parameter
+     * will return if any admin has blocked the uninstallation. Before L MR1, passing {@code null}
+     * will cause a NullPointerException to be raised.
      *
      * @param admin The name of the admin component whose blocking policy will be checked, or
-     *              {@code null} to check whether any admin has blocked the uninstallation.
+     *            {@code null} to check whether any admin has blocked the uninstallation.
      * @param packageName package to check.
      * @return true if uninstallation is blocked.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public boolean isUninstallBlocked(@Nullable ComponentName admin, String packageName) {
         if (mService != null) {
@@ -5200,19 +5259,18 @@
     }
 
     /**
-     * Called by the profile owner of a managed profile 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 parent profile, for example the home screen. Note that
-     * a package may have zero or more provider components, where each component
-     * provides a different widget type.
+     * Called by the profile owner of a managed profile 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 parent profile, 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.
      *
      * @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.
-     *
+     * @throws SecurityException if {@code admin} is not a profile owner.
      * @see #removeCrossProfileWidgetProvider(android.content.ComponentName, String)
      * @see #getCrossProfileWidgetProviders(android.content.ComponentName)
      */
@@ -5229,17 +5287,16 @@
 
     /**
      * Called by the profile owner of a managed profile 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)}.
+     * 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.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @param packageName The package from which widget providers are no longer
-     *     white-listed.
+     * @param packageName The package from which widget providers are no longer white-listed.
      * @return Whether the package was removed.
-     *
+     * @throws SecurityException if {@code admin} is not a profile owner.
      * @see #addCrossProfileWidgetProvider(android.content.ComponentName, String)
      * @see #getCrossProfileWidgetProviders(android.content.ComponentName)
      */
@@ -5261,9 +5318,9 @@
      *
      * @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)
+     * @throws SecurityException if {@code admin} is not a profile owner.
      */
     public List<String> getCrossProfileWidgetProviders(@NonNull ComponentName admin) {
         if (mService != null) {
@@ -5284,6 +5341,7 @@
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param icon the bitmap to set as the photo.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
     public void setUserIcon(@NonNull ComponentName admin, Bitmap icon) {
         try {
@@ -5298,10 +5356,10 @@
      * {@link #ACTION_SYSTEM_UPDATE_POLICY_CHANGED} is broadcasted.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with. All
-     *              components in the device owner package can set system update policies and the
-     *              most recent policy takes
-     * effect.
+     *            components in the device owner package can set system update policies and the most
+     *            recent policy takes effect.
      * @param policy the new policy, or {@code null} to clear the current policy.
+     * @throws SecurityException if {@code admin} is not a device owner.
      * @see SystemUpdatePolicy
      */
     public void setSystemUpdatePolicy(@NonNull ComponentName admin, SystemUpdatePolicy policy) {
@@ -5332,17 +5390,17 @@
 
     /**
      * Called by a device owner to disable the keyguard altogether.
-     *
-     * <p>Setting the keyguard to disabled has the same effect as choosing "None" as the screen
-     * lock type. However, this call has no effect if a password, pin or pattern is currently set.
-     * If a password, pin or pattern is set after the keyguard was disabled, the keyguard stops
-     * being disabled.
+     * <p>
+     * Setting the keyguard to disabled has the same effect as choosing "None" as the screen lock
+     * type. However, this call has no effect if a password, pin or pattern is currently set. If a
+     * password, pin or pattern is set after the keyguard was disabled, the keyguard stops being
+     * disabled.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param disabled {@code true} disables the keyguard, {@code false} reenables it.
-     *
      * @return {@code false} if attempting to disable the keyguard while a lock password was in
-     * place. {@code true} otherwise.
+     *         place. {@code true} otherwise.
+     * @throws SecurityException if {@code admin} is not a device owner.
      */
     public boolean setKeyguardDisabled(@NonNull ComponentName admin, boolean disabled) {
         try {
@@ -5354,14 +5412,13 @@
 
     /**
      * Called by device owner to disable the status bar. Disabling the status bar blocks
-     * notifications, quick settings and other screen overlays that allow escaping from
-     * a single use device.
+     * notifications, quick settings and other screen overlays that allow escaping from a single use
+     * device.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param disabled {@code true} disables the status bar, {@code false} reenables it.
-     *
-     * @return {@code false} if attempting to disable the status bar failed.
-     * {@code true} otherwise.
+     * @return {@code false} if attempting to disable the status bar failed. {@code true} otherwise.
+     * @throws SecurityException if {@code admin} is not a device owner.
      */
     public boolean setStatusBarDisabled(@NonNull ComponentName admin, boolean disabled) {
         try {
@@ -5393,19 +5450,19 @@
 
     /**
      * Called by profile or device owners to set the default response for future runtime permission
-     * requests by applications. The policy can allow for normal operation which prompts the
-     * user to grant a permission, or can allow automatic granting or denying of runtime
-     * permission requests by an application. This also applies to new permissions declared by app
-     * updates. When a permission is denied or granted this way, the effect is equivalent to setting
-     * the permission grant state via {@link #setPermissionGrantState}.
-     *
-     * <p/>As this policy only acts on runtime permission requests, it only applies to applications
+     * requests by applications. The policy can allow for normal operation which prompts the user to
+     * grant a permission, or can allow automatic granting or denying of runtime permission requests
+     * by an application. This also applies to new permissions declared by app updates. When a
+     * permission is denied or granted this way, the effect is equivalent to setting the permission
+     * grant state via {@link #setPermissionGrantState}.
+     * <p/>
+     * As this policy only acts on runtime permission requests, it only applies to applications
      * built with a {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#M} or later.
      *
      * @param admin Which profile or device owner this request is associated with.
      * @param policy One of the policy constants {@link #PERMISSION_POLICY_PROMPT},
-     * {@link #PERMISSION_POLICY_AUTO_GRANT} and {@link #PERMISSION_POLICY_AUTO_DENY}.
-     *
+     *            {@link #PERMISSION_POLICY_AUTO_GRANT} and {@link #PERMISSION_POLICY_AUTO_DENY}.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      * @see #setPermissionGrantState
      */
     public void setPermissionPolicy(@NonNull ComponentName admin, int policy) {
@@ -5431,29 +5488,28 @@
     }
 
     /**
-     * Sets the grant state of a runtime permission for a specific application. The state
-     * can be {@link #PERMISSION_GRANT_STATE_DEFAULT default} in which a user can manage it
-     * through the UI, {@link #PERMISSION_GRANT_STATE_DENIED denied}, in which the permission
-     * is denied and the user cannot manage it through the UI, and {@link
-     * #PERMISSION_GRANT_STATE_GRANTED granted} in which the permission is granted and the
-     * user cannot manage it through the UI. This might affect all permissions in a
-     * group that the runtime permission belongs to. This method can only be called
+     * Sets the grant state of a runtime permission for a specific application. The state can be
+     * {@link #PERMISSION_GRANT_STATE_DEFAULT default} in which a user can manage it through the UI,
+     * {@link #PERMISSION_GRANT_STATE_DENIED denied}, in which the permission is denied and the user
+     * cannot manage it through the UI, and {@link #PERMISSION_GRANT_STATE_GRANTED granted} in which
+     * the permission is granted and the user cannot manage it through the UI. This might affect all
+     * permissions in a group that the runtime permission belongs to. This method can only be called
      * by a profile or device owner.
-     *
-     * <p/>Setting the grant state to {@link #PERMISSION_GRANT_STATE_DEFAULT default} does not
-     * revoke the permission. It retains the previous grant, if any.
-     *
-     * <p/>Permissions can be granted or revoked only for applications built with a
+     * <p/>
+     * Setting the grant state to {@link #PERMISSION_GRANT_STATE_DEFAULT default} does not revoke
+     * the permission. It retains the previous grant, if any.
+     * <p/>
+     * Permissions can be granted or revoked only for applications built with a
      * {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#M} or later.
      *
      * @param admin Which profile or device owner this request is associated with.
      * @param packageName The application to grant or revoke a permission to.
      * @param permission The permission to grant or revoke.
-     * @param grantState The permission grant state which is one of {@link
-     *         #PERMISSION_GRANT_STATE_DENIED}, {@link #PERMISSION_GRANT_STATE_DEFAULT},
-     *         {@link #PERMISSION_GRANT_STATE_GRANTED},
+     * @param grantState The permission grant state which is one of
+     *            {@link #PERMISSION_GRANT_STATE_DENIED}, {@link #PERMISSION_GRANT_STATE_DEFAULT},
+     *            {@link #PERMISSION_GRANT_STATE_GRANTED},
      * @return whether the permission was successfully granted or revoked.
-     *
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      * @see #PERMISSION_GRANT_STATE_DENIED
      * @see #PERMISSION_GRANT_STATE_DEFAULT
      * @see #PERMISSION_GRANT_STATE_GRANTED
@@ -5474,13 +5530,15 @@
      * @param packageName The application to check the grant state for.
      * @param permission The permission to check for.
      * @return the current grant state specified by device policy. If the profile or device owner
-     * has not set a grant state, the return value is {@link #PERMISSION_GRANT_STATE_DEFAULT}.
-     * This does not indicate whether or not the permission is currently granted for the package.
-     *
-     * <p/>If a grant state was set by the profile or device owner, then the return value will
-     * be one of {@link #PERMISSION_GRANT_STATE_DENIED} or {@link #PERMISSION_GRANT_STATE_GRANTED},
-     * which indicates if the permission is currently denied or granted.
-     *
+     *         has not set a grant state, the return value is
+     *         {@link #PERMISSION_GRANT_STATE_DEFAULT}. This does not indicate whether or not the
+     *         permission is currently granted for the package.
+     *         <p/>
+     *         If a grant state was set by the profile or device owner, then the return value will
+     *         be one of {@link #PERMISSION_GRANT_STATE_DENIED} or
+     *         {@link #PERMISSION_GRANT_STATE_GRANTED}, which indicates if the permission is
+     *         currently denied or granted.
+     * @throws SecurityException if {@code admin} is not a device or profile owner.
      * @see #setPermissionGrantState(ComponentName, String, String, int)
      * @see PackageManager#checkPermission(String, String)
      */
@@ -5546,10 +5604,11 @@
      * Called by device owner to get the MAC address of the Wi-Fi device.
      *
      * @param admin Which device owner this request is associated with.
-     * @return the MAC address of the Wi-Fi device, or null when the information is not
-     * available. (For example, Wi-Fi hasn't been enabled, or the device doesn't support Wi-Fi.)
-     *
-     * <p>The address will be in the {@code XX:XX:XX:XX:XX:XX} format.
+     * @return the MAC address of the Wi-Fi device, or null when the information is not available.
+     *         (For example, Wi-Fi hasn't been enabled, or the device doesn't support Wi-Fi.)
+     *         <p>
+     *         The address will be in the {@code XX:XX:XX:XX:XX:XX} format.
+     * @throws SecurityException if {@code admin} is not a device owner.
      */
     public String getWifiMacAddress(@NonNull ComponentName admin) {
         try {
@@ -5560,7 +5619,12 @@
     }
 
     /**
-     * Called by device owner to reboot the device.
+     * Called by device owner to reboot the device. If there is an ongoing call on the device,
+     * throws an {@link IllegalStateException}.
+     * @param admin Which device owner the request is associated with.
+     * @throws IllegalStateException if device has an ongoing call.
+     * @throws SecurityException if {@code admin} is not a device owner.
+     * @see TelephonyManager#CALL_STATE_IDLE
      */
     public void reboot(@NonNull ComponentName admin) {
         try {
@@ -5571,24 +5635,21 @@
     }
 
     /**
-     * Called by a device admin to set the short support message. This will
-     * be displayed to the user in settings screens where funtionality has
-     * been disabled by the admin.
-     *
-     * The message should be limited to a short statement such as
-     * "This setting is disabled by your administrator. Contact someone@example.com
-     *  for support."
-     * If the message is longer than 200 characters it may be truncated.
-     *
-     * <p>If the short support message needs to be localized, it is the responsibility of the
+     * Called by a device admin to set the short support message. This will be displayed to the user
+     * in settings screens where funtionality has been disabled by the admin. The message should be
+     * limited to a short statement such as "This setting is disabled by your administrator. Contact
+     * someone@example.com for support." If the message is longer than 200 characters it may be
+     * truncated.
+     * <p>
+     * If the short support message needs to be localized, it is the responsibility of the
      * {@link DeviceAdminReceiver} to listen to the {@link Intent#ACTION_LOCALE_CHANGED} broadcast
      * and set a new version of this string accordingly.
      *
      * @see #setLongSupportMessage
-     *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @param message Short message to be displayed to the user in settings or null to
-     *        clear the existing message.
+     * @param message Short message to be displayed to the user in settings or null to clear the
+     *            existing message.
+     * @throws SecurityException if {@code admin} is not an active administrator.
      */
     public void setShortSupportMessage(@NonNull ComponentName admin,
             @Nullable String message) {
@@ -5605,8 +5666,9 @@
      * Called by a device admin to get the short support message.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @return The message set by {@link #setShortSupportMessage(ComponentName, String)}
-     *         or null if no message has been set.
+     * @return The message set by {@link #setShortSupportMessage(ComponentName, String)} or null if
+     *         no message has been set.
+     * @throws SecurityException if {@code admin} is not an active administrator.
      */
     public String getShortSupportMessage(@NonNull ComponentName admin) {
         if (mService != null) {
@@ -5620,18 +5682,18 @@
     }
 
     /**
-     * Called by a device admin to set the long support message. This will
-     * be displayed to the user in the device administators settings screen.
-     *
-     * <p>If the long support message needs to be localized, it is the responsibility of the
+     * Called by a device admin to set the long support message. This will be displayed to the user
+     * in the device administators settings screen.
+     * <p>
+     * If the long support message needs to be localized, it is the responsibility of the
      * {@link DeviceAdminReceiver} to listen to the {@link Intent#ACTION_LOCALE_CHANGED} broadcast
      * and set a new version of this string accordingly.
      *
      * @see #setShortSupportMessage
-     *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @param message Long message to be displayed to the user in settings or null to
-     *        clear the existing message.
+     * @param message Long message to be displayed to the user in settings or null to clear the
+     *            existing message.
+     * @throws SecurityException if {@code admin} is not an active administrator.
      */
     public void setLongSupportMessage(@NonNull ComponentName admin,
             @Nullable String message) {
@@ -5648,8 +5710,9 @@
      * Called by a device admin to get the long support message.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @return The message set by {@link #setLongSupportMessage(ComponentName, String)}
-     *         or null if no message has been set.
+     * @return The message set by {@link #setLongSupportMessage(ComponentName, String)} or null if
+     *         no message has been set.
+     * @throws SecurityException if {@code admin} is not an active administrator.
      */
     public String getLongSupportMessage(@NonNull ComponentName admin) {
         if (mService != null) {
@@ -5706,10 +5769,11 @@
     /**
      * Called by the profile owner of a managed profile to obtain a {@link DevicePolicyManager}
      * whose calls act on the parent profile.
-     *
-     * <p> Note only some methods will work on the parent Manager.
+     * <p>
+     * Note only some methods will work on the parent Manager.
      *
      * @return a new instance of {@link DevicePolicyManager} that acts on the parent profile.
+     * @throws SecurityException if {@code admin} is not a profile owner.
      */
     public DevicePolicyManager getParentProfileInstance(@NonNull ComponentName admin) {
         try {
@@ -5723,17 +5787,18 @@
     }
 
     /**
-     * Called by device owner to control the device logging feature. Logging can only be
-     * enabled on single user devices where the sole user is managed by the device owner.
-     *
-     * <p> Device logs contain various information intended for security auditing purposes.
-     * See {@link SecurityEvent} for details.
-     *
-     * <p>There must be only one user on the device, managed by the device owner.
-     * Otherwise a {@link SecurityException} will be thrown.
+     * Called by device owner to control the device logging feature. Logging can only be enabled on
+     * single user devices where the sole user is managed by the device owner.
+     * <p>
+     * Device logs contain various information intended for security auditing purposes. See
+     * {@link SecurityEvent} for details.
+     * <p>
+     * There must be only one user on the device, managed by the device owner. Otherwise a
+     * {@link SecurityException} will be thrown.
      *
      * @param admin Which device owner this request is associated with.
      * @param enabled whether device logging should be enabled or not.
+     * @throws SecurityException if {@code admin} is not a device owner.
      * @see #retrieveDeviceLogs
      */
     public void setDeviceLoggingEnabled(@NonNull ComponentName admin, boolean enabled) {
@@ -5746,12 +5811,12 @@
 
     /**
      * Return whether device logging is enabled or not by the device owner.
-     *
-     * <p>Can only be called by the device owner, otherwise a {@link SecurityException} will be
-     * thrown.
+     * <p>
+     * Can only be called by the device owner, otherwise a {@link SecurityException} will be thrown.
      *
      * @param admin Which device owner this request is associated with.
      * @return {@code true} if device logging is enabled by device owner, {@code false} otherwise.
+     * @throws SecurityException if {@code admin} is not a device owner.
      */
     public boolean getDeviceLoggingEnabled(@NonNull ComponentName admin) {
         try {
@@ -5762,18 +5827,19 @@
     }
 
     /**
-     * Called by device owner to retrieve all new device logging entries since the last call to
-     * this API after device boots.
-     *
-     * <p> Access to the logs is rate limited and it will only return new logs after the device
-     * owner has been notified via {@link DeviceAdminReceiver#onSecurityLogsAvailable}.
-     *
-     * <p>There must be only one user on the device, managed by the device owner.
-     * Otherwise a {@link SecurityException} will be thrown.
+     * Called by device owner to retrieve all new device logging entries since the last call to this
+     * API after device boots.
+     * <p>
+     * Access to the logs is rate limited and it will only return new logs after the device owner
+     * has been notified via {@link DeviceAdminReceiver#onSecurityLogsAvailable}.
+     * <p>
+     * There must be only one user on the device, managed by the device owner. Otherwise a
+     * {@link SecurityException} will be thrown.
      *
      * @param admin Which device owner this request is associated with.
-     * @return the new batch of device logs which is a list of {@link SecurityEvent},
-     * or {@code null} if rate limitation is exceeded or if logging is currently disabled.
+     * @return the new batch of device logs which is a list of {@link SecurityEvent}, or
+     *         {@code null} if rate limitation is exceeded or if logging is currently disabled.
+     * @throws SecurityException if {@code admin} is not a device owner.
      */
     public List<SecurityEvent> retrieveDeviceLogs(@NonNull ComponentName admin) {
         try {
@@ -5807,18 +5873,18 @@
 
     /**
      * Called by device owners to retrieve device logs from before the device's last reboot.
-     *
      * <p>
      * <strong> The device logs are retrieved from a RAM region which is not guaranteed to be
-     * corruption-free during power cycles, due to hardware variations and limitations. As a
-     * result, this API is provided as best-effort and the returned logs may contain corrupted data.
-     * </strong>
-     *
-     * <p>There must be only one user on the device, managed by the device owner.
-     * Otherwise a {@link SecurityException} will be thrown.
+     * corruption-free during power cycles, due to hardware variations and limitations. As a result,
+     * this API is provided as best-effort and the returned logs may contain corrupted
+     * data. </strong>
+     * <p>
+     * There must be only one user on the device, managed by the device owner. Otherwise a
+     * {@link SecurityException} will be thrown.
      *
      * @param admin Which device owner this request is associated with.
      * @return Device logs from before the latest reboot of the system.
+     * @throws SecurityException if {@code admin} is not a device owner.
      */
     public List<SecurityEvent> retrievePreviousDeviceLogs(@NonNull ComponentName admin) {
         try {
@@ -5830,15 +5896,16 @@
     }
 
     /**
-     * Called by a profile owner of a managed profile to set the color used for customization.
-     * This color is used as background color of the confirm credentials screen for that user.
-     * The default color is {@link android.graphics.Color#GRAY}.
-     *
-     * <p>The confirm credentials screen can be created using
+     * Called by a profile owner of a managed profile to set the color used for customization. This
+     * color is used as background color of the confirm credentials screen for that user. The
+     * default color is {@link android.graphics.Color#GRAY}.
+     * <p>
+     * The confirm credentials screen can be created using
      * {@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent}.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param color The 32bit representation of the color to be used.
+     * @throws SecurityException if {@code admin} is not a profile owner.
      */
     public void setOrganizationColor(@NonNull ComponentName admin, int color) {
         try {
@@ -5873,6 +5940,7 @@
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @return The 32bit representation of the color to be used.
+     * @throws SecurityException if {@code admin} is not a profile owner.
      */
     public int getOrganizationColor(@NonNull ComponentName admin) {
         try {
@@ -5900,13 +5968,14 @@
     /**
      * Called by a profile owner of a managed profile to set the name of the organization under
      * management.
-     *
-     * <p>If the organization name needs to be localized, it is the responsibility of the
+     * <p>
+     * If the organization name needs to be localized, it is the responsibility of the
      * {@link DeviceAdminReceiver} to listen to the {@link Intent#ACTION_LOCALE_CHANGED} broadcast
      * and set a new version of this string accordingly.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param title The organization name or {@code null} to clear a previously set name.
+     * @throws SecurityException if {@code admin} is not a profile owner.
      */
     public void setOrganizationName(@NonNull ComponentName admin, @Nullable String title) {
         try {
@@ -5917,11 +5986,12 @@
     }
 
     /**
-     * Called by a profile owner of a managed profile to retrieve the name of the organization
-     * under management.
+     * Called by a profile owner of a managed profile to retrieve the name of the organization under
+     * management.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @return The organization name or {@code null} if none is set.
+     * @throws SecurityException if {@code admin} is not a profile owner.
      */
     public String getOrganizationName(@NonNull ComponentName admin) {
         try {
diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java
index 61b40d4..54a2f7a 100644
--- a/core/java/android/app/admin/DevicePolicyManagerInternal.java
+++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java
@@ -16,6 +16,7 @@
 
 package android.app.admin;
 
+import android.content.Intent;
 import android.os.UserHandle;
 
 import java.util.List;
@@ -74,10 +75,23 @@
 
     /**
      * Checks if a given package has a device or a profile owner for the given user.
-     * </br><em>Does <b>not</b> support negative userIds like {@link UserHandle#USER_ALL}</em>
+     * <p>
+     * <em>Note: does <b>not</b> support negative userIds like {@link UserHandle#USER_ALL}</em>
+     *
      * @param packageName The package to check
      * @param userId the userId to check for.
      * @return true if package has a device or profile owner, false otherwise.
      */
     public abstract boolean hasDeviceOwnerOrProfileOwner(String packageName, int userId);
+
+    /**
+     * Creates an intent to show the admin support dialog to let the user know that the package is
+     * suspended by the admin. This assumes that {@param packageName} is suspended by the
+     * device/profile owner. The caller should check if the package is suspended or not.
+     *
+     * @param packageName The package that is suspended
+     * @param userId The user having the suspended package.
+     * @return The intent to trigger the admin support dialog.
+     */
+    public abstract Intent createPackageSuspendedDialogIntent(String packageName, int userId);
 }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index dc73e26..c38496d 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -91,7 +91,7 @@
 
     int setStorageEncryption(in ComponentName who, boolean encrypt);
     boolean getStorageEncryption(in ComponentName who, int userHandle);
-    int getStorageEncryptionStatus(int userHandle);
+    int getStorageEncryptionStatus(in String callerPackage, int userHandle);
 
     boolean requestBugreport(in ComponentName who);
 
diff --git a/core/java/android/app/usage/NetworkStats.java b/core/java/android/app/usage/NetworkStats.java
index 9f1a9cf0..6d5c81b 100644
--- a/core/java/android/app/usage/NetworkStats.java
+++ b/core/java/android/app/usage/NetworkStats.java
@@ -16,6 +16,7 @@
 
 package android.app.usage;
 
+import android.annotation.IntDef;
 import android.content.Context;
 import android.net.INetworkStatsService;
 import android.net.INetworkStatsSession;
@@ -29,6 +30,9 @@
 
 import dalvik.system.CloseGuard;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Class providing enumeration over buckets of network usage statistics. {@link NetworkStats} objects
  * are returned as results to various queries in {@link NetworkStatsManager}.
@@ -119,6 +123,11 @@
      * aggregated (e.g. time or state) some values may be equal across all buckets.
      */
     public static class Bucket {
+        /** @hide */
+        @IntDef({STATE_ALL, STATE_DEFAULT, STATE_FOREGROUND})
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface State {}
+
         /**
          * Combined usage across all states.
          */
@@ -149,20 +158,34 @@
          */
         public static final int UID_TETHERING = TrafficStats.UID_TETHERING;
 
+        /** @hide */
+        @IntDef({ROAMING_ALL, ROAMING_NO, ROAMING_YES})
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Roaming {}
+
         /**
-         * Combined usage across all roaming states.
+         * Combined usage across all roaming states. Covers both roaming and non-roaming usage.
          */
         public static final int ROAMING_ALL = -1;
 
         /**
-         * Usage not accounted for in any other roaming state.
+         * Usage that occurs on a home, non-roaming network.
+         *
+         * <p>Any cellular usage in this bucket was incurred while the device was connected to a
+         * tower owned or operated by the user's wireless carrier, or a tower that the user's
+         * wireless carrier has indicated should be treated as a home network regardless.
+         *
+         * <p>This is also the default value for network types that do not support roaming.
          */
-        public static final int ROAMING_DEFAULT = 0x1;
+        public static final int ROAMING_NO = 0x1;
 
         /**
-         * Roaming usage.
+         * Usage that occurs on a roaming network.
+         *
+         * <p>Any cellular usage in this bucket as incurred while the device was roaming on another
+         * carrier's network, for which additional charges may apply.
          */
-        public static final int ROAMING_ROAMING = 0x2;
+        public static final int ROAMING_YES = 0x2;
 
         /**
          * Special TAG value matching any tag.
@@ -185,7 +208,7 @@
         private long mTxBytes;
         private long mTxPackets;
 
-        private static int convertState(int networkStatsSet) {
+        private static @State int convertState(int networkStatsSet) {
             switch (networkStatsSet) {
                 case android.net.NetworkStats.SET_ALL : return STATE_ALL;
                 case android.net.NetworkStats.SET_DEFAULT : return STATE_DEFAULT;
@@ -210,11 +233,11 @@
             return tag;
         }
 
-        private static int convertRoaming(int roaming) {
+        private static @Roaming int convertRoaming(int roaming) {
             switch (roaming) {
                 case android.net.NetworkStats.ROAMING_ALL : return ROAMING_ALL;
-                case android.net.NetworkStats.ROAMING_DEFAULT : return ROAMING_DEFAULT;
-                case android.net.NetworkStats.ROAMING_ROAMING : return ROAMING_ROAMING;
+                case android.net.NetworkStats.ROAMING_NO: return ROAMING_NO;
+                case android.net.NetworkStats.ROAMING_YES: return ROAMING_YES;
             }
             return 0;
         }
@@ -252,7 +275,7 @@
          * </ul>
          * @return Usage state.
          */
-        public int getState() {
+        public @State int getState() {
             return mState;
         }
 
@@ -260,11 +283,11 @@
          * Roaming state. One of the following values:<p/>
          * <ul>
          * <li>{@link #ROAMING_ALL}</li>
-         * <li>{@link #ROAMING_DEFAULT}</li>
-         * <li>{@link #ROAMING_ROAMING}</li>
+         * <li>{@link #ROAMING_NO}</li>
+         * <li>{@link #ROAMING_YES}</li>
          * </ul>
          */
-        public int getRoaming() {
+        public @Roaming int getRoaming() {
             return mRoaming;
         }
 
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index eb4cb91..d762a17 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009-2015 The Android Open Source Project
+ * Copyright (C) 2009-2016 The Android Open Source Project
  * Copyright (C) 2015 Samsung LSI
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -1837,6 +1837,9 @@
         } else if (profile == BluetoothProfile.SAP) {
             BluetoothSap sap = new BluetoothSap(context, listener);
             return true;
+        } else if (profile == BluetoothProfile.PBAP_CLIENT) {
+            BluetoothPbapClient pbapClient = new BluetoothPbapClient(context, listener);
+            return true;
         } else {
             return false;
         }
@@ -1905,6 +1908,10 @@
                 BluetoothSap sap = (BluetoothSap)proxy;
                 sap.close();
                 break;
+            case BluetoothProfile.PBAP_CLIENT:
+                BluetoothPbapClient pbapClient = (BluetoothPbapClient)proxy;
+                pbapClient.close();
+                break;
         }
     }
 
diff --git a/core/java/android/bluetooth/BluetoothPbapClient.java b/core/java/android/bluetooth/BluetoothPbapClient.java
new file mode 100644
index 0000000..736e55d
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothPbapClient.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2016 The Android Open Source 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 java.util.List;
+import java.util.ArrayList;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.RemoteException;
+import android.os.IBinder;
+import android.util.Log;
+
+/**
+ * This class provides the APIs to control the Bluetooth PBAP Client Profile.
+ *@hide
+ */
+public final class BluetoothPbapClient implements BluetoothProfile {
+
+    private static final String TAG = "BluetoothPbapClient";
+    private static final boolean DBG = false;
+    private static final boolean VDBG = false;
+
+    public static final String ACTION_CONNECTION_STATE_CHANGED =
+        "android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED";
+
+    private IBluetoothPbapClient mService;
+    private BluetoothDevice mDevice;
+    private final Context mContext;
+    private ServiceListener mServiceListener;
+    private BluetoothAdapter mAdapter;
+
+    /** There was an error trying to obtain the state */
+    public static final int STATE_ERROR        = -1;
+
+    public static final int RESULT_FAILURE = 0;
+    public static final int RESULT_SUCCESS = 1;
+    /** Connection canceled before completion. */
+    public static final int RESULT_CANCELED = 2;
+
+    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+            new IBluetoothStateChangeCallback.Stub() {
+                public void onBluetoothStateChange(boolean up) {
+                    if (DBG) {
+                        Log.d(TAG, "onBluetoothStateChange: PBAP CLIENT up=" + up);
+                    }
+                    if (!up) {
+                        if (VDBG) {
+                            Log.d(TAG,"Unbinding service...");
+                        }
+                        synchronized (mConnection) {
+                            try {
+                                mService = null;
+                                mContext.unbindService(mConnection);
+                            } catch (Exception re) {
+                                Log.e(TAG,"",re);
+                            }
+                        }
+                    } else {
+                        synchronized (mConnection) {
+                            try {
+                                if (mService == null) {
+                                    if (VDBG) {
+                                        Log.d(TAG,"Binding service...");
+                                    }
+                                    doBind();
+                                }
+                            } catch (Exception re) {
+                                Log.e(TAG,"",re);
+                            }
+                        }
+                    }
+                }
+        };
+
+    /**
+     * Create a BluetoothPbapClient proxy object.
+     */
+    BluetoothPbapClient(Context context, ServiceListener l) {
+        if (DBG) {
+            Log.d(TAG, "Create BluetoothPbapClient proxy object");
+        }
+        mContext = context;
+        mServiceListener = l;
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (RemoteException e) {
+                Log.e(TAG,"",e);
+            }
+        }
+        doBind();
+    }
+
+    private boolean doBind() {
+        Intent intent = new Intent(IBluetoothPbapClient.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(comp);
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
+            Log.e(TAG, "Could not bind to Bluetooth PBAP Client Service with " + intent);
+            return false;
+        }
+        return true;
+    }
+
+    protected void finalize() throws Throwable {
+        try {
+            close();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * Close the connection to the backing service.
+     * Other public functions of BluetoothPbapClient will return default error
+     * results once close() has been called. Multiple invocations of close()
+     * are ok.
+     */
+    public synchronized void close() {
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (Exception e) {
+                Log.e(TAG,"",e);
+            }
+        }
+
+        synchronized (mConnection) {
+            if (mService != null) {
+                try {
+                    mService = null;
+                    mContext.unbindService(mConnection);
+                } catch (Exception re) {
+                    Log.e(TAG,"",re);
+                }
+            }
+        }
+        mServiceListener = null;
+    }
+
+    /**
+     * Initiate connection.
+     * Upon successful connection to remote PBAP server the Client will
+     * attempt to automatically download the users phonebook and call log.
+     *
+     * @param device    a remote device we want connect to
+     * @return <code>true</code> if command has been issued successfully;
+     *         <code>false</code> otherwise;
+     */
+    public boolean connect(BluetoothDevice device) {
+        if (DBG) {
+            log("connect(" + device + ") for PBAP Client.");
+        }
+        if (mService != null && isEnabled() && isValidDevice(device)) {
+            try {
+                mDevice = device;
+                return mService.connect(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (mService == null) {
+            Log.w(TAG, "Proxy not attached to service");
+        }
+        return false;
+    }
+
+    /**
+     * Initiate disconnect.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on error,
+     *               true otherwise
+     */
+    public boolean disconnect() {
+        if (DBG) {
+            log("disconnect(" + mDevice + ")");
+        }
+        if (mService != null && isEnabled() && isValidDevice(mDevice)) {
+            try {
+                mService.disconnect(mDevice);
+                return true;
+            } catch (RemoteException e) {
+              Log.e(TAG, Log.getStackTraceString(new Throwable()));
+              return false;
+            }
+        }
+        if (mService == null) {
+            Log.w(TAG, "Proxy not attached to service");
+        }
+        return false;
+    }
+
+    /**
+     * Get the list of connected devices.
+     * Currently at most one.
+     *
+     * @return list of connected devices
+     */
+    @Override
+    public List<BluetoothDevice> getConnectedDevices() {
+        if (DBG) {
+            log("getConnectedDevices()");
+        }
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.getConnectedDevices();
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return new ArrayList<BluetoothDevice>();
+            }
+        }
+        if (mService == null) {
+            Log.w(TAG, "Proxy not attached to service");
+        }
+        return new ArrayList<BluetoothDevice>();
+    }
+
+    /**
+     * Get the list of devices matching specified states. Currently at most one.
+     *
+     * @return list of matching devices
+     */
+    @Override
+    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+        if (DBG) {
+            log("getDevicesMatchingStates()");
+        }
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.getDevicesMatchingConnectionStates(states);
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return new ArrayList<BluetoothDevice>();
+            }
+        }
+        if (mService == null) {
+            Log.w(TAG, "Proxy not attached to service");
+        }
+        return new ArrayList<BluetoothDevice>();
+    }
+
+    /**
+     * Get connection state of device
+     *
+     * @return device connection state
+     */
+    @Override
+    public int getConnectionState(BluetoothDevice device) {
+        if (DBG) {
+            log("getConnectionState(" + device + ")");
+        }
+        if (mService != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return mService.getConnectionState(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return BluetoothProfile.STATE_DISCONNECTED;
+            }
+        }
+        if (mService == null) {
+            Log.w(TAG, "Proxy not attached to service");
+        }
+        return BluetoothProfile.STATE_DISCONNECTED;
+    }
+
+    private final ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            if (DBG) {
+                log("Proxy object connected");
+            }
+            mService = IBluetoothPbapClient.Stub.asInterface(service);
+            if (mServiceListener != null) {
+                mServiceListener.onServiceConnected(BluetoothProfile.PBAP_CLIENT, BluetoothPbapClient.this);
+            }
+        }
+        public void onServiceDisconnected(ComponentName className) {
+            if (DBG) {
+                log("Proxy object disconnected");
+            }
+            mService = null;
+            if (mServiceListener != null) {
+                mServiceListener.onServiceDisconnected(BluetoothProfile.PBAP_CLIENT);
+            }
+        }
+    };
+
+    private static void log(String msg) {
+        Log.d(TAG, msg);
+    }
+
+    private boolean isEnabled() {
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        if (adapter != null && adapter.getState() == BluetoothAdapter.STATE_ON) {
+            return true;
+        }
+        log("Bluetooth is Not enabled");
+        return false;
+    }
+
+    private boolean isValidDevice(BluetoothDevice device) {
+       if (device == null) {
+           return false;
+       }
+       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
+           return true;
+       }
+       return false;
+    }
+}
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index cbce22c..eee66d1 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -131,6 +131,12 @@
     public static final int HEADSET_CLIENT = 16;
 
     /**
+     * PBAP Client
+     * @hide
+     */
+    public static final int PBAP_CLIENT = 17;
+
+    /**
      * Default priority for devices that we try to auto-connect to and
      * and allow incoming connections for the profile
      * @hide
diff --git a/core/java/android/bluetooth/IBluetoothPbapClient.aidl b/core/java/android/bluetooth/IBluetoothPbapClient.aidl
new file mode 100644
index 0000000..b26ea29
--- /dev/null
+++ b/core/java/android/bluetooth/IBluetoothPbapClient.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 The Android Open Source 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.BluetoothDevice;
+
+/**
+ * API for Bluetooth Phone Book Access Provile Client Side
+ *
+ * {@hide}
+ */
+interface IBluetoothPbapClient {
+    boolean connect(in BluetoothDevice device);
+    boolean disconnect(in BluetoothDevice device);
+    List<BluetoothDevice> getConnectedDevices();
+    List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
+    int getConnectionState(in BluetoothDevice device);
+}
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 4e1b6e0..441f188 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -2440,6 +2440,28 @@
         }
     }
 
+    /** {@hide} */
+    public void putCache(Uri key, Bundle value) {
+        try {
+            getContentService().putCache(mContext.getPackageName(), key, value,
+                    mContext.getUserId());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** {@hide} */
+    public Bundle getCache(Uri key) {
+        try {
+            final Bundle bundle = getContentService().getCache(mContext.getPackageName(), key,
+                    mContext.getUserId());
+            if (bundle != null) bundle.setClassLoader(mContext.getClassLoader());
+            return bundle;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     /**
      * Returns sampling percentage for a given duration.
      *
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 825dd5b..ccb0552 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2742,7 +2742,7 @@
      * <dt> {@link #NETWORK_STATS_SERVICE} ("netstats")
      * <dd> A {@link android.app.usage.NetworkStatsManager NetworkStatsManager} for querying network
      * usage statistics.
-     * <dt> {@link #HARDWARE_PROPERTIES_SERVICE} ("hardwareproperties")
+     * <dt> {@link #HARDWARE_PROPERTIES_SERVICE} ("hardware_properties")
      * <dd> A {@link android.os.HardwarePropertiesManager} for accessing hardware properties.
      * </dl>
      *
@@ -3574,7 +3574,7 @@
      *
      * @see #getSystemService
      */
-    public static final String HARDWARE_PROPERTIES_SERVICE = "hardwareproperties";
+    public static final String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
 
     /**
      * TODO Javadoc
diff --git a/core/java/android/content/IContentService.aidl b/core/java/android/content/IContentService.aidl
index 8b471a0..d47e780 100644
--- a/core/java/android/content/IContentService.aidl
+++ b/core/java/android/content/IContentService.aidl
@@ -179,6 +179,8 @@
             int userId);
 
     void addStatusChangeListener(int mask, ISyncStatusObserver callback);
-
     void removeStatusChangeListener(ISyncStatusObserver callback);
+
+    void putCache(in String packageName, in Uri key, in Bundle value, int userId);
+    Bundle getCache(in String packageName, in Uri key, int userId);
 }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 09fa5e1..35dbc34 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -660,6 +660,8 @@
     /**
      * Activity Action: Quick view the data. Launches a quick viewer for
      * a URI or a list of URIs.
+     * <p>Activities handling this intent action should handle the vast majority of
+     * MIME types rather than only specific ones.
      * <p>Input: {@link #getData} is a mandatory content URI of the item to
      * preview. {@link #getClipData} contains an optional list of content URIs
      * if there is more than one item to preview. {@link #EXTRA_INDEX} is an
@@ -4142,7 +4144,8 @@
 
     /**
      * Optional index with semantics depending on the intent action.
-     * @see #ACTION_QUICK_VIEW
+     *
+     * <p>The value must be an integer greater or equal to 0.
      */
     public static final String EXTRA_INDEX = "android.intent.extra.INDEX";
 
@@ -4560,7 +4563,8 @@
     /**
      * This flag is only used in split-screen multi-window mode. The new activity will be displayed
      * adjacent to the one launching it. This can only be used in conjunction with
-     * {@link #FLAG_ACTIVITY_NEW_TASK}.
+     * {@link #FLAG_ACTIVITY_NEW_TASK}. Also, setting {@link #FLAG_ACTIVITY_MULTIPLE_TASK} is
+     * required if you want a new instance of an existing activity to be created.
      */
     public static final int FLAG_ACTIVITY_LAUNCH_ADJACENT = 0x00001000;
 
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 14ef61c..5da3c86 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.content.res.Configuration;
+import android.content.res.Configuration.NativeConfig;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Printer;
@@ -495,6 +496,28 @@
     @ScreenOrientation
     public int screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
 
+    /** @hide */
+    @IntDef(flag = true,
+            value = {
+                    CONFIG_MCC,
+                    CONFIG_MNC,
+                    CONFIG_LOCALE,
+                    CONFIG_TOUCHSCREEN,
+                    CONFIG_KEYBOARD,
+                    CONFIG_KEYBOARD_HIDDEN,
+                    CONFIG_NAVIGATION,
+                    CONFIG_ORIENTATION,
+                    CONFIG_SCREEN_LAYOUT,
+                    CONFIG_UI_MODE,
+                    CONFIG_SCREEN_SIZE,
+                    CONFIG_SMALLEST_SCREEN_SIZE,
+                    CONFIG_DENSITY,
+                    CONFIG_LAYOUT_DIRECTION,
+                    CONFIG_FONT_SCALE,
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Config {}
+
     /**
      * Bit in {@link #configChanges} that indicates that the activity
      * can itself handle changes to the IMSI MCC.  Set from the
@@ -629,7 +652,7 @@
      *
      * @hide
      */
-    public static int activityInfoConfigToNative(int input) {
+    public static @NativeConfig int activityInfoConfigJavaToNative(@Config int input) {
         int output = 0;
         for (int i = 0; i < CONFIG_NATIVE_BITS.length; i++) {
             if ((input & (1 << i)) != 0) {
@@ -644,7 +667,7 @@
      *
      * @hide
      */
-    public static int activityInfoConfigNativeToJava(int input) {
+    public static @Config int activityInfoConfigNativeToJava(@NativeConfig int input) {
         int output = 0;
         for (int i = 0; i < CONFIG_NATIVE_BITS.length; i++) {
             if ((input & CONFIG_NATIVE_BITS[i]) != 0) {
diff --git a/core/java/android/content/pm/ILauncherApps.aidl b/core/java/android/content/pm/ILauncherApps.aidl
index b1d3f20..6b3d4f1 100644
--- a/core/java/android/content/pm/ILauncherApps.aidl
+++ b/core/java/android/content/pm/ILauncherApps.aidl
@@ -34,7 +34,7 @@
  * {@hide}
  */
 interface ILauncherApps {
-    void addOnAppsChangedListener(in IOnAppsChangedListener listener);
+    void addOnAppsChangedListener(String callingPackage, in IOnAppsChangedListener listener);
     void removeOnAppsChangedListener(in IOnAppsChangedListener listener);
     ParceledListSlice getLauncherActivities(String packageName, in UserHandle user);
     ResolveInfo resolveActivity(in Intent intent, in UserHandle user);
@@ -58,4 +58,6 @@
     int getShortcutIconResId(String callingPackage, in ShortcutInfo shortcut, in UserHandle user);
     ParcelFileDescriptor getShortcutIconFd(String callingPackage, in ShortcutInfo shortcut,
             in UserHandle user);
+
+    boolean hasShortcutHostPermission(String callingPackage);
 }
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index a6a732e..8724d5e 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -16,11 +16,9 @@
 
 package android.content.pm;
 
-import android.Manifest.permission;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -30,7 +28,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -159,6 +156,9 @@
          * Indicates that one or more shortcuts (which may be dynamic and/or pinned)
          * have been added, updated or removed.
          *
+         * <p>Only the applications that are allowed to access the shortcut information,
+         * as defined in {@link #hasShortcutHostPermission()}, will receive it.
+         *
          * @param packageName The name of the package that has the shortcuts.
          * @param shortcuts all shortcuts from the package (dynamic and/or pinned).
          * @param user The UserHandle of the profile that generated the change.
@@ -395,16 +395,34 @@
     }
 
     /**
+     * Returns whether the caller can access the shortcut information.
+     *
+     * <p>Only the default launcher can access the shortcut information.
+     *
+     * <p>Note when this method returns {@code false}, that may be a temporary situation because
+     * the user is trying a new launcher application.  The user may decide to change the default
+     * launcher to the calling application again, so even if a launcher application loses
+     * this permission, it does <b>not</b> have to purge pinned shortcut information.
+     */
+    public boolean hasShortcutHostPermission() {
+        try {
+            return mService.hasShortcutHostPermission(mContext.getPackageName());
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Returns the IDs of {@link ShortcutInfo}s that match {@code query}.
      *
-     * <p>Callers mut have the {@link permission#BIND_APPWIDGET} permission.
+     * <p>Callers must be allowed to access the shortcut information, as defined in {@link
+     * #hasShortcutHostPermission()}.
      *
      * @param query result includes shortcuts matching this query.
      * @param user The UserHandle of the profile.
      *
      * @return the IDs of {@link ShortcutInfo}s that match the query.
      */
-    @RequiresPermission(permission.BIND_APPWIDGET)
     @Nullable
     public List<ShortcutInfo> getShortcuts(@NonNull ShortcutQuery query,
             @NonNull UserHandle user) {
@@ -420,7 +438,8 @@
     /**
      * Returns {@link ShortcutInfo}s with the given IDs from a package.
      *
-     * <p>Callers mut have the {@link permission#BIND_APPWIDGET} permission.
+     * <p>Callers must be allowed to access the shortcut information, as defined in {@link
+     * #hasShortcutHostPermission()}.
      *
      * @param packageName The target package.
      * @param ids IDs of the shortcuts to retrieve.
@@ -428,7 +447,6 @@
      *
      * @return list of {@link ShortcutInfo} associated with the package.
      */
-    @RequiresPermission(permission.BIND_APPWIDGET)
     @Nullable
     public List<ShortcutInfo> getShortcutInfo(@NonNull String packageName,
             @NonNull List<String> ids, @NonNull UserHandle user) {
@@ -447,13 +465,13 @@
      * <p>This API is <b>NOT</b> cumulative; this will replace all pinned shortcuts for the package.
      * However, different launchers may have different set of pinned shortcuts.
      *
-     * <p>Callers must have the {@link permission#BIND_APPWIDGET} permission.
+     * <p>Callers must be allowed to access the shortcut information, as defined in {@link
+     * #hasShortcutHostPermission()}.
      *
      * @param packageName The target package name.
      * @param shortcutIds The IDs of the shortcut to be pinned.
      * @param user The UserHandle of the profile.
      */
-    @RequiresPermission(permission.BIND_APPWIDGET)
     public void pinShortcuts(@NonNull String packageName, @NonNull List<String> shortcutIds,
             @NonNull UserHandle user) {
         try {
@@ -467,12 +485,12 @@
      * Return the icon resource ID, if {@code shortcut} has one
      * (i.e. when {@link ShortcutInfo#hasIconResource()} returns {@code true}).
      *
-     * <p>Callers mut have the {@link permission#BIND_APPWIDGET} permission.
+     * <p>Callers must be allowed to access the shortcut information, as defined in {@link
+     * #hasShortcutHostPermission()}.
      *
      * @param shortcut The target shortcut.
      * @param user The UserHandle of the profile.
      */
-    @RequiresPermission(permission.BIND_APPWIDGET)
     public int getShortcutIconResId(@NonNull ShortcutInfo shortcut, @NonNull UserHandle user) {
         try {
             return mService.getShortcutIconResId(mContext.getPackageName(), shortcut, user);
@@ -485,12 +503,12 @@
      * Return the icon as {@link ParcelFileDescriptor}, when it's stored as a file
      * (i.e. when {@link ShortcutInfo#hasIconFile()} returns {@code true}).
      *
-     * <p>Callers mut have the {@link permission#BIND_APPWIDGET} permission.
+     * <p>Callers must be allowed to access the shortcut information, as defined in {@link
+     * #hasShortcutHostPermission()}.
      *
      * @param shortcut The target shortcut.
      * @param user The UserHandle of the profile.
      */
-    @RequiresPermission(permission.BIND_APPWIDGET)
     public ParcelFileDescriptor getShortcutIconFd(
             @NonNull ShortcutInfo shortcut, @NonNull UserHandle user) {
         try {
@@ -503,7 +521,8 @@
     /**
      * Launches a shortcut.
      *
-     * <p>Callers mut have the {@link permission#BIND_APPWIDGET} permission.
+     * <p>Callers must be allowed to access the shortcut information, as defined in {@link
+     * #hasShortcutHostPermission()}.
      *
      * @param packageName The target shortcut package name.
      * @param shortcutId The target shortcut ID.
@@ -513,7 +532,6 @@
      * @return {@code false} when the shortcut is no longer valid (e.g. the creator application
      *   has been uninstalled). {@code true} when the shortcut is still valid.
      */
-    @RequiresPermission(permission.BIND_APPWIDGET)
     public boolean startShortcut(@NonNull String packageName, @NonNull String shortcutId,
             @Nullable Rect sourceBounds, @Nullable Bundle startActivityOptions,
             @NonNull UserHandle user) {
@@ -547,7 +565,8 @@
                 addCallbackLocked(callback, handler);
                 if (addedFirstCallback) {
                     try {
-                        mService.addOnAppsChangedListener(mAppsChangedListener);
+                        mService.addOnAppsChangedListener(mContext.getPackageName(),
+                                mAppsChangedListener);
                     } catch (RemoteException re) {
                         throw re.rethrowFromSystemServer();
                     }
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 0f5ec91..6f2786a 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1054,8 +1054,12 @@
 
         /** {@hide} */
         @SystemApi
-        public void setInstallFlagsDowngrade() {
-            installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
+        public void setAllowDowngrade(boolean allowDowngrade) {
+            if (allowDowngrade) {
+                installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
+            } else {
+                installFlags &= ~PackageManager.INSTALL_ALLOW_DOWNGRADE;
+            }
         }
 
         /** {@hide} */
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 89f2fc4..13ebb82 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -16,6 +16,7 @@
 
 package android.content.pm;
 
+import android.content.ComponentName;
 import android.content.pm.PackageManager.NameNotFoundException;
 
 import java.util.List;
@@ -140,4 +141,10 @@
      *             found on the system.
      */
     public abstract ApplicationInfo getApplicationInfo(String packageName, int userId);
+
+    /**
+     * Interface to {@link com.android.server.pm.PackageManagerService#getHomeActivitiesAsUser}.
+     */
+    public abstract ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
+            int userId);
 }
diff --git a/core/java/android/content/pm/ShortcutServiceInternal.java b/core/java/android/content/pm/ShortcutServiceInternal.java
index 918c763..4255582 100644
--- a/core/java/android/content/pm/ShortcutServiceInternal.java
+++ b/core/java/android/content/pm/ShortcutServiceInternal.java
@@ -36,8 +36,7 @@
  */
 public abstract class ShortcutServiceInternal {
     public interface ShortcutChangeListener {
-        void onShortcutChanged(@NonNull String packageName,
-                @NonNull List<ShortcutInfo> shortcuts, @UserIdInt int userId);
+        void onShortcutChanged(@NonNull String packageName, @UserIdInt int userId);
     }
 
     public abstract List<ShortcutInfo>
@@ -63,4 +62,6 @@
 
     public abstract ParcelFileDescriptor getShortcutIconFd(@NonNull String callingPackage,
             @NonNull ShortcutInfo shortcut, int userId);
+
+    public abstract boolean hasShortcutHostPermission(@NonNull String callingPackage, int userId);
 }
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 7b0b98d..4ad86f7 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -21,6 +21,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.StringRes;
+import android.content.res.Configuration.NativeConfig;
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 import android.util.SparseArray;
@@ -796,7 +797,10 @@
     /*package*/ static final int STYLE_DATA = 1;
     /*package*/ static final int STYLE_ASSET_COOKIE = 2;
     /*package*/ static final int STYLE_RESOURCE_ID = 3;
-    /*package*/ static final int STYLE_CHANGING_CONFIGURATIONS = 4;
+
+    /* Offset within typed data array for native changingConfigurations. */
+    static final int STYLE_CHANGING_CONFIGURATIONS = 4;
+
     /*package*/ static final int STYLE_DENSITY = 5;
     /*package*/ native static final boolean applyStyle(long theme,
             int defStyleAttr, int defStyleRes, long xmlParser,
@@ -845,7 +849,7 @@
                                                                 TypedValue outValue,
                                                                 boolean resolve);
     /*package*/ native static final void dumpTheme(long theme, int priority, String tag, String prefix);
-    /*package*/ native static final int getThemeChangingConfigurations(long theme);
+    /*package*/ native static final @NativeConfig int getThemeChangingConfigurations(long theme);
 
     private native final long openXmlAssetNative(int cookie, String fileName);
 
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index 9e1b312..fb5bfd3 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -19,6 +19,7 @@
 import android.annotation.ColorInt;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.Resources.Theme;
 import android.graphics.Color;
 
@@ -82,7 +83,7 @@
     private ColorStateListFactory mFactory;
 
     private int[][] mThemeAttrs;
-    private int mChangingConfigurations;
+    private @Config int mChangingConfigurations;
 
     private int[][] mStateSpecs;
     private int[] mColors;
@@ -251,7 +252,7 @@
         int depth;
         int type;
 
-        int changingConfigurations = 0;
+        @Config int changingConfigurations = 0;
         int defaultColor = DEFAULT_COLOR;
 
         boolean hasUnresolvedAttrs = false;
@@ -440,8 +441,8 @@
      *
      * @see android.content.pm.ActivityInfo
      */
-    public int getChangingConfigurations() {
-        return mChangingConfigurations;
+    public @Config int getChangingConfigurations() {
+        return super.getChangingConfigurations() | mChangingConfigurations;
     }
 
     private int modulateColorAlpha(int baseColor, float alphaMod) {
@@ -620,7 +621,7 @@
         }
 
         @Override
-        public int getChangingConfigurations() {
+        public @Config int getChangingConfigurations() {
             return mSrc.mChangingConfigurations;
         }
 
diff --git a/core/java/android/content/res/ComplexColor.java b/core/java/android/content/res/ComplexColor.java
index d96ec62..b297764 100644
--- a/core/java/android/content/res/ComplexColor.java
+++ b/core/java/android/content/res/ComplexColor.java
@@ -25,6 +25,8 @@
  * {@link android.content.res.ColorStateList} or {@link android.content.res.GradientColor}
  */
 public abstract class ComplexColor {
+    private int mChangingConfigurations;
+
     /**
      * @return {@code true}  if this ComplexColor changes color based on state, {@code false}
      * otherwise.
@@ -52,4 +54,24 @@
      * @hide only for resource preloading
      */
     public abstract ComplexColor obtainForTheme(Theme t);
+
+    /**
+     * @hide only for resource preloading
+     */
+    final void setBaseChangingConfigurations(int changingConfigurations) {
+        mChangingConfigurations = changingConfigurations;
+    }
+
+    /**
+     * Returns a mask of the configuration parameters for which this color
+     * may change, requiring that it be re-created.
+     *
+     * @return a mask of the changing configuration parameters, as defined by
+     *         {@link android.content.pm.ActivityInfo}
+     *
+     * @see android.content.pm.ActivityInfo
+     */
+    public int getChangingConfigurations() {
+        return mChangingConfigurations;
+    }
 }
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index be4f895..9b1d462 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -22,8 +22,11 @@
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.pm.ActivityInfo;
+import android.content.pm.ActivityInfo.Config;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -32,6 +35,8 @@
 import android.view.View;
 
 import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Locale;
 
@@ -663,6 +668,28 @@
      */
     public int seq;
 
+    /** @hide */
+    @IntDef(flag = true,
+            value = {
+                    NATIVE_CONFIG_MCC,
+                    NATIVE_CONFIG_MNC,
+                    NATIVE_CONFIG_LOCALE,
+                    NATIVE_CONFIG_TOUCHSCREEN,
+                    NATIVE_CONFIG_KEYBOARD,
+                    NATIVE_CONFIG_KEYBOARD_HIDDEN,
+                    NATIVE_CONFIG_NAVIGATION,
+                    NATIVE_CONFIG_ORIENTATION,
+                    NATIVE_CONFIG_DENSITY,
+                    NATIVE_CONFIG_SCREEN_SIZE,
+                    NATIVE_CONFIG_VERSION,
+                    NATIVE_CONFIG_SCREEN_LAYOUT,
+                    NATIVE_CONFIG_UI_MODE,
+                    NATIVE_CONFIG_SMALLEST_SCREEN_SIZE,
+                    NATIVE_CONFIG_LAYOUTDIR,
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface NativeConfig {}
+
     /** @hide Native-specific bit mask for MCC config; DO NOT USE UNLESS YOU ARE SURE. */
     public static final int NATIVE_CONFIG_MCC = 0x0001;
     /** @hide Native-specific bit mask for MNC config; DO NOT USE UNLESS YOU ARE SURE. */
@@ -917,14 +944,13 @@
     }
 
     /**
-     * Copy the fields from delta into this Configuration object, keeping
-     * track of which ones have changed.  Any undefined fields in
-     * <var>delta</var> are ignored and not copied in to the current
-     * Configuration.
-     * @return Returns a bit mask of the changed fields, as per
-     * {@link #diff}.
+     * Copies the fields from delta into this Configuration object, keeping
+     * track of which ones have changed. Any undefined fields in {@code delta}
+     * are ignored and not copied in to the current Configuration.
+     *
+     * @return a bit mask of the changed fields, as per {@link #diff}
      */
-    public int updateFrom(Configuration delta) {
+    public @Config int updateFrom(@NonNull Configuration delta) {
         int changed = 0;
         if (delta.fontScale > 0 && fontScale != delta.fontScale) {
             changed |= ActivityInfo.CONFIG_FONT_SCALE;
@@ -1171,17 +1197,19 @@
     }
 
     /**
-     * Determine if a new resource needs to be loaded from the bit set of
+     * Determines if a new resource needs to be loaded from the bit set of
      * configuration changes returned by {@link #updateFrom(Configuration)}.
      *
-     * @param configChanges The mask of changes configurations as returned by
-     * {@link #updateFrom(Configuration)}.
-     * @param interestingChanges The configuration changes that the resource
-     * can handled, as given in {@link android.util.TypedValue#changingConfigurations}.
-     *
-     * @return Return true if the resource needs to be loaded, else false.
+     * @param configChanges the mask of changes configurations as returned by
+     *                      {@link #updateFrom(Configuration)}
+     * @param interestingChanges the configuration changes that the resource
+     *                           can handle as given in
+     *                           {@link android.util.TypedValue#changingConfigurations}
+     * @return {@code true} if the resource needs to be loaded, {@code false}
+     *         otherwise
      */
-    public static boolean needNewResources(int configChanges, int interestingChanges) {
+    public static boolean needNewResources(@Config int configChanges,
+            @Config int interestingChanges) {
         return (configChanges & (interestingChanges|ActivityInfo.CONFIG_FONT_SCALE)) != 0;
     }
 
diff --git a/core/java/android/content/res/ConfigurationBoundResourceCache.java b/core/java/android/content/res/ConfigurationBoundResourceCache.java
index 40d2a82..70290c4 100644
--- a/core/java/android/content/res/ConfigurationBoundResourceCache.java
+++ b/core/java/android/content/res/ConfigurationBoundResourceCache.java
@@ -16,6 +16,8 @@
 
 package android.content.res;
 
+import android.content.pm.ActivityInfo.Config;
+
 /**
  * A Cache class which can be used to cache resource objects that are easy to clone but more
  * expensive to inflate.
@@ -42,7 +44,7 @@
     }
 
     @Override
-    public boolean shouldInvalidateEntry(ConstantState<T> entry, int configChanges) {
+    public boolean shouldInvalidateEntry(ConstantState<T> entry, @Config int configChanges) {
         return Configuration.needNewResources(configChanges, entry.getChangingConfigurations());
     }
 }
diff --git a/core/java/android/content/res/ConstantState.java b/core/java/android/content/res/ConstantState.java
index ee609df..09d4a59 100644
--- a/core/java/android/content/res/ConstantState.java
+++ b/core/java/android/content/res/ConstantState.java
@@ -15,6 +15,8 @@
 */
 package android.content.res;
 
+import android.content.pm.ActivityInfo.Config;
+
 /**
  * A cache class that can provide new instances of a particular resource which may change
  * depending on the current {@link Resources.Theme} or {@link Configuration}.
@@ -33,7 +35,7 @@
      * Return a bit mask of configuration changes that will impact
      * this resource (and thus require completely reloading it).
      */
-    abstract public int getChangingConfigurations();
+    abstract public @Config int getChangingConfigurations();
 
     /**
      * Create a new instance without supplying resources the caller
diff --git a/core/java/android/content/res/GradientColor.java b/core/java/android/content/res/GradientColor.java
index cc46cbd..f29656a 100644
--- a/core/java/android/content/res/GradientColor.java
+++ b/core/java/android/content/res/GradientColor.java
@@ -20,6 +20,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.Resources.Theme;
 
 import com.android.internal.R;
@@ -83,7 +84,7 @@
     /** Lazily-created factory for this GradientColor. */
     private GradientColorFactory mFactory;
 
-    private int mChangingConfigurations;
+    private @Config int mChangingConfigurations;
     private int mDefaultColor;
 
     // After parsing all the attributes from XML, this shader is the ultimate result containing
@@ -506,7 +507,7 @@
         }
 
         @Override
-        public int getChangingConfigurations() {
+        public @Config int getChangingConfigurations() {
             return mSrc.mChangingConfigurations;
         }
 
@@ -541,6 +542,19 @@
         return clone;
     }
 
+    /**
+     * Returns a mask of the configuration parameters for which this gradient
+     * may change, requiring that it be re-created.
+     *
+     * @return a mask of the changing configuration parameters, as defined by
+     *         {@link android.content.pm.ActivityInfo}
+     *
+     * @see android.content.pm.ActivityInfo
+     */
+    public int getChangingConfigurations() {
+        return super.getChangingConfigurations() | mChangingConfigurations;
+    }
+
     private void applyTheme(Theme t) {
         if (mThemeAttrs != null) {
             applyRootAttrsTheme(t);
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index 0858cb8..a364010 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -15,6 +15,9 @@
  */
 package android.content.res;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
 import android.animation.Animator;
 import android.animation.StateListAnimator;
 import android.annotation.AnyRes;
@@ -26,6 +29,7 @@
 import android.annotation.StyleRes;
 import android.annotation.StyleableRes;
 import android.content.pm.ActivityInfo;
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.Resources.NotFoundException;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
@@ -40,8 +44,6 @@
 import android.util.Slog;
 import android.util.TypedValue;
 import android.util.Xml;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.InputStream;
 import java.util.Arrays;
@@ -65,7 +67,7 @@
     private static final boolean TRACE_FOR_PRELOAD = false;
     private static final boolean TRACE_FOR_MISS_PRELOAD = false;
 
-    private static final int LAYOUT_DIR_CONFIG = ActivityInfo.activityInfoConfigToNative(
+    private static final int LAYOUT_DIR_CONFIG = ActivityInfo.activityInfoConfigJavaToNative(
             ActivityInfo.CONFIG_LAYOUT_DIRECTION);
 
     private static final int ID_OTHER = 0x01000004;
@@ -331,7 +333,7 @@
             // the framework.
             mCompatibilityInfo.applyToDisplayMetrics(mMetrics);
 
-            final int configChanges = calcConfigChanges(config);
+            final @Config int configChanges = calcConfigChanges(config);
 
             LocaleList locales = mConfiguration.getLocales();
             if (locales.isEmpty()) {
@@ -395,26 +397,30 @@
     }
 
     /**
-     * Called by ConfigurationBoundResourceCacheTest.
+     * Applies the new configuration, returning a bitmask of the changes
+     * between the old and new configurations.
+     *
+     * @param config the new configuration
+     * @return bitmask of config changes
      */
-    public int calcConfigChanges(Configuration config) {
-        int configChanges = 0xfffffff;
-        if (config != null) {
-            mTmpConfig.setTo(config);
-            int density = config.densityDpi;
-            if (density == Configuration.DENSITY_DPI_UNDEFINED) {
-                density = mMetrics.noncompatDensityDpi;
-            }
-
-            mCompatibilityInfo.applyToConfiguration(density, mTmpConfig);
-
-            if (mTmpConfig.getLocales().isEmpty()) {
-                mTmpConfig.setLocales(LocaleList.getDefault());
-            }
-            configChanges = mConfiguration.updateFrom(mTmpConfig);
-            configChanges = ActivityInfo.activityInfoConfigToNative(configChanges);
+    public @Config int calcConfigChanges(@Nullable Configuration config) {
+        if (config == null) {
+            // If there is no configuration, assume all flags have changed.
+            return 0xFFFFFFFF;
         }
-        return configChanges;
+
+        mTmpConfig.setTo(config);
+        int density = config.densityDpi;
+        if (density == Configuration.DENSITY_DPI_UNDEFINED) {
+            density = mMetrics.noncompatDensityDpi;
+        }
+
+        mCompatibilityInfo.applyToConfiguration(density, mTmpConfig);
+
+        if (mTmpConfig.getLocales().isEmpty()) {
+            mTmpConfig.setLocales(LocaleList.getDefault());
+        }
+        return mConfiguration.updateFrom(mTmpConfig);
     }
 
     /**
@@ -593,8 +599,8 @@
         }
     }
 
-    private boolean verifyPreloadConfig(int changingConfigurations, int allowVarying,
-            int resourceId, String name) {
+    private boolean verifyPreloadConfig(@Config int changingConfigurations,
+            @Config int allowVarying, @AnyRes int resourceId, @Nullable String name) {
         // We allow preloading of resources even if they vary by font scale (which
         // doesn't impact resource selection) or density (which we handle specially by
         // simply turning off all preloading), as well as any other configs specified
@@ -707,9 +713,11 @@
         }
 
         if (complexColor != null) {
+            complexColor.setBaseChangingConfigurations(value.changingConfigurations);
+
             if (mPreloading) {
-                if (verifyPreloadConfig(value.changingConfigurations, 0, value.resourceId,
-                        "color")) {
+                if (verifyPreloadConfig(complexColor.getChangingConfigurations(),
+                        0, value.resourceId, "color")) {
                     sPreloadedComplexColors.put(key, complexColor.getConstantState());
                 }
             } else {
@@ -1104,7 +1112,7 @@
             return mAssets.getStyleAttributes(getAppliedStyleResId());
         }
 
-        int getChangingConfigurations() {
+        @Config int getChangingConfigurations() {
             synchronized (mKey) {
                 final int nativeChangingConfig =
                         AssetManager.getThemeChangingConfigurations(mTheme);
diff --git a/core/java/android/content/res/ThemedResourceCache.java b/core/java/android/content/res/ThemedResourceCache.java
index 9a2d06147..f1b1e74 100644
--- a/core/java/android/content/res/ThemedResourceCache.java
+++ b/core/java/android/content/res/ThemedResourceCache.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.Resources.Theme;
 import android.content.res.Resources.ThemeKey;
 import android.util.LongSparseArray;
@@ -115,7 +116,7 @@
      *
      * @param configChanges a bitmask of configuration changes
      */
-    public void onConfigurationChange(int configChanges) {
+    public void onConfigurationChange(@Config int configChanges) {
         prune(configChanges);
     }
 
@@ -192,7 +193,7 @@
      *                      simply prune missing weak references
      * @return {@code true} if the cache is completely empty after pruning
      */
-    private boolean prune(int configChanges) {
+    private boolean prune(@Config int configChanges) {
         synchronized (this) {
             if (mThemedEntries != null) {
                 for (int i = mThemedEntries.size() - 1; i >= 0; i--) {
@@ -211,7 +212,7 @@
     }
 
     private boolean pruneEntriesLocked(@Nullable LongSparseArray<WeakReference<T>> entries,
-            int configChanges) {
+            @Config int configChanges) {
         if (entries == null) {
             return true;
         }
@@ -226,7 +227,7 @@
         return entries.size() == 0;
     }
 
-    private boolean pruneEntryLocked(@Nullable T entry, int configChanges) {
+    private boolean pruneEntryLocked(@Nullable T entry, @Config int configChanges) {
         return entry == null || (configChanges != 0
                 && shouldInvalidateEntry(entry, configChanges));
     }
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 022bdfb..f6ac0ba 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -20,6 +20,8 @@
 import android.annotation.ColorInt;
 import android.annotation.Nullable;
 import android.annotation.StyleableRes;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ActivityInfo.Config;
 import android.graphics.drawable.Drawable;
 import android.os.StrictMode;
 import android.util.AttributeSet;
@@ -252,7 +254,8 @@
      * @throws RuntimeException if the TypedArray has already been recycled.
      * @hide
      */
-    public String getNonConfigurationString(@StyleableRes int index, int allowedChangingConfigs) {
+    public String getNonConfigurationString(@StyleableRes int index,
+            @Config int allowedChangingConfigs) {
         if (mRecycled) {
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
@@ -260,7 +263,9 @@
         index *= AssetManager.STYLE_NUM_ENTRIES;
         final int[] data = mData;
         final int type = data[index+AssetManager.STYLE_TYPE];
-        if ((data[index+AssetManager.STYLE_CHANGING_CONFIGURATIONS]&~allowedChangingConfigs) != 0) {
+        final @Config int changingConfigs = ActivityInfo.activityInfoConfigNativeToJava(
+                data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]);
+        if ((changingConfigs & ~allowedChangingConfigs) != 0) {
             return null;
         }
         if (type == TypedValue.TYPE_NULL) {
@@ -1155,12 +1160,12 @@
      * @throws RuntimeException if the TypedArray has already been recycled.
      * @see android.content.pm.ActivityInfo
      */
-    public int getChangingConfigurations() {
+    public @Config int getChangingConfigurations() {
         if (mRecycled) {
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        int changingConfig = 0;
+        @Config int changingConfig = 0;
 
         final int[] data = mData;
         final int N = length();
@@ -1170,7 +1175,8 @@
             if (type == TypedValue.TYPE_NULL) {
                 continue;
             }
-            changingConfig |= data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS];
+            changingConfig |= ActivityInfo.activityInfoConfigNativeToJava(
+                    data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]);
         }
         return changingConfig;
     }
@@ -1185,7 +1191,8 @@
         outValue.data = data[index+AssetManager.STYLE_DATA];
         outValue.assetCookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
         outValue.resourceId = data[index+AssetManager.STYLE_RESOURCE_ID];
-        outValue.changingConfigurations = data[index+AssetManager.STYLE_CHANGING_CONFIGURATIONS];
+        outValue.changingConfigurations = ActivityInfo.activityInfoConfigNativeToJava(
+                data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]);
         outValue.density = data[index+AssetManager.STYLE_DENSITY];
         outValue.string = (type == TypedValue.TYPE_STRING) ? loadStringValueAt(index) : null;
         return true;
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 2826882..6b79a8a 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -2269,8 +2269,9 @@
     public void onExtractedDeleteText(int start, int end) {
         InputConnection conn = getCurrentInputConnection();
         if (conn != null) {
+            conn.finishComposingText();
             conn.setSelection(start, start);
-            conn.deleteSurroundingText(0, end-start);
+            conn.deleteSurroundingText(0, end - start);
         }
     }
 
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 3d8b091..25806fa 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -71,9 +71,9 @@
     /** {@link #set} value for all roaming values. */
     public static final int ROAMING_ALL = -1;
     /** {@link #set} value where native, non-roaming data is accounted. */
-    public static final int ROAMING_DEFAULT = 0;
+    public static final int ROAMING_NO = 0;
     /** {@link #set} value where roaming data is accounted. */
-    public static final int ROAMING_ROAMING = 1;
+    public static final int ROAMING_YES = 1;
 
     // TODO: move fields to "mVariable" notation
 
@@ -123,7 +123,7 @@
 
         public Entry(String iface, int uid, int set, int tag, long rxBytes, long rxPackets,
                 long txBytes, long txPackets, long operations) {
-            this(iface, uid, set, tag, ROAMING_DEFAULT, rxBytes, rxPackets, txBytes, txPackets,
+            this(iface, uid, set, tag, ROAMING_NO, rxBytes, rxPackets, txBytes, txPackets,
                     operations);
         }
 
@@ -836,10 +836,10 @@
         switch (roaming) {
             case ROAMING_ALL:
                 return "ALL";
-            case ROAMING_DEFAULT:
-                return "DEFAULT";
-            case ROAMING_ROAMING:
-                return "ROAMING";
+            case ROAMING_NO:
+                return "NO";
+            case ROAMING_YES:
+                return "YES";
             default:
                 return "UNKNOWN";
         }
@@ -1019,18 +1019,18 @@
         // Caveat: if the vpn software uses tag, the total tagged traffic may be greater than
         // the TAG_NONE traffic.
         //
-        // Relies on the fact that the underlying traffic only has state ROAMING_DEFAULT, which
+        // Relies on the fact that the underlying traffic only has state ROAMING_NO, which
         // should be the case as it comes directly from the /proc file. We only blend in the
         // roaming data after applying these adjustments, by checking the NetworkIdentity of the
         // underlying iface.
         int idxVpnBackground = findIndex(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE,
-                ROAMING_DEFAULT);
+                ROAMING_NO);
         if (idxVpnBackground != -1) {
             tunSubtract(idxVpnBackground, this, moved);
         }
 
         int idxVpnForeground = findIndex(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE,
-                ROAMING_DEFAULT);
+                ROAMING_NO);
         if (idxVpnForeground != -1) {
             tunSubtract(idxVpnForeground, this, moved);
         }
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index ddcd635..b25b33d 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -434,25 +434,35 @@
             String filename = packageFile.getCanonicalPath();
             Log.w(TAG, "!!! REBOOTING TO INSTALL " + filename + " !!!");
 
-            if (!processed && filename.startsWith("/data/")) {
-                FileWriter uncryptFile = new FileWriter(UNCRYPT_PACKAGE_FILE);
-                try {
-                    uncryptFile.write(filename + "\n");
-                } finally {
-                    uncryptFile.close();
-                }
-                // UNCRYPT_PACKAGE_FILE needs to be readable and writable by system server.
-                if (!UNCRYPT_PACKAGE_FILE.setReadable(true, false)
-                        || !UNCRYPT_PACKAGE_FILE.setWritable(true, false)) {
-                    Log.e(TAG, "Error setting permission for " + UNCRYPT_PACKAGE_FILE);
-                }
-
-                BLOCK_MAP_FILE.delete();
-            }
-
-            // If the package is on the /data partition, use the block map file as
-            // the package name instead.
+            // If the package is on the /data partition, the package needs to
+            // be processed (i.e. uncrypt'd). The caller specifies if that has
+            // been done in 'processed' parameter.
             if (filename.startsWith("/data/")) {
+                if (processed) {
+                    if (!BLOCK_MAP_FILE.exists()) {
+                        Log.e(TAG, "Package claimed to have been processed but failed to find "
+                                + "the block map file.");
+                        throw new IOException("Failed to find block map file");
+                    }
+                } else {
+                    FileWriter uncryptFile = new FileWriter(UNCRYPT_PACKAGE_FILE);
+                    try {
+                        uncryptFile.write(filename + "\n");
+                    } finally {
+                        uncryptFile.close();
+                    }
+                    // UNCRYPT_PACKAGE_FILE needs to be readable and writable
+                    // by system server.
+                    if (!UNCRYPT_PACKAGE_FILE.setReadable(true, false)
+                            || !UNCRYPT_PACKAGE_FILE.setWritable(true, false)) {
+                        Log.e(TAG, "Error setting permission for " + UNCRYPT_PACKAGE_FILE);
+                    }
+
+                    BLOCK_MAP_FILE.delete();
+                }
+
+                // If the package is on the /data partition, use the block map
+                // file as the package name instead.
                 filename = "@/cache/recovery/block.map";
             }
 
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index e7c4a07..e2ae133 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -179,6 +179,7 @@
          * <li>{@link #VOICEMAIL_TYPE}</li>
          * <li>{@link #REJECTED_TYPE}</li>
          * <li>{@link #BLOCKED_TYPE}</li>
+         * <li>{@link #ANSWERED_EXTERNALLY_TYPE}</li>
          * </ul>
          * </p>
          */
@@ -196,6 +197,12 @@
         public static final int REJECTED_TYPE = 5;
         /** Call log type for calls blocked automatically. */
         public static final int BLOCKED_TYPE = 6;
+        /**
+         * Call log type for a call which was answered on another device.  Used in situations where
+         * a call rings on multiple devices simultaneously and it ended up being answered on a
+         * device other than the current one.
+         */
+        public static final int ANSWERED_EXTERNALLY_TYPE = 7;
 
         /**
          * Bit-mask describing features of the call (e.g. video).
@@ -207,6 +214,9 @@
         /** Call had video. */
         public static final int FEATURES_VIDEO = 0x1;
 
+        /** Call was pulled externally. */
+        public static final int FEATURES_PULLED_EXTERNALLY = 0x2;
+
         /**
          * The phone number as the user entered it.
          * <P>Type: TEXT</P>
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index e7a9b7d..4ad7969 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -379,8 +379,18 @@
          * @see DocumentsProvider#queryChildDocuments(String, String[], String)
          * @hide
          */
-
         public static final int FLAG_ARCHIVE = 1 << 15;
+
+        /**
+         * Flag indicating that a document is not complete, likely its
+         * contents are being downloaded. Partial files cannot be opened,
+         * copied, moved in the UI. But they can be deleted and retried
+         * if they represent a failed download.
+         *
+         * @see #COLUMN_FLAGS
+         * @hide
+         */
+        public static final int FLAG_PARTIAL = 1 << 16;
     }
 
     /**
diff --git a/core/java/android/util/TypedValue.java b/core/java/android/util/TypedValue.java
index 98aaa81..bd00aba 100644
--- a/core/java/android/util/TypedValue.java
+++ b/core/java/android/util/TypedValue.java
@@ -17,6 +17,7 @@
 package android.util;
 
 import android.annotation.AnyRes;
+import android.content.pm.ActivityInfo.Config;
 
 /**
  * Container for a dynamically typed data value.  Primarily used with
@@ -183,9 +184,11 @@
     @AnyRes
     public int resourceId;
 
-    /** If Value came from a resource, these are the configurations for which
-     *  its contents can change. */
-    public int changingConfigurations = -1;
+    /**
+     * If the value came from a resource, these are the configurations for
+     * which its contents can change.
+     */
+    public @Config int changingConfigurations = -1;
 
     /**
      * If the Value came from a resource, this holds the corresponding pixel density.
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 1269ad9..22d5ed8 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import android.annotation.IntDef;
 import android.annotation.RequiresPermission;
 import android.content.Context;
 import android.content.res.CompatibilityInfo;
@@ -31,6 +32,8 @@
 import android.util.DisplayMetrics;
 import android.util.Log;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
 
 import static android.Manifest.permission.CONFIGURE_DISPLAY_COLOR_TRANSFORM;
@@ -715,6 +718,14 @@
     }
 
     /**
+     * Returns the display's HDR capabilities.
+     * @hide
+     */
+    public HdrCapabilities getHdrCapabilities() {
+        return new HdrCapabilities();
+    }
+
+    /**
      * Gets the supported color transforms of this device.
      * @hide
      */
@@ -762,14 +773,23 @@
 
     /**
      * Gets display metrics that describe the size and density of this display.
-     * <p>
-     * The size is adjusted based on the current rotation of the display.
-     * </p><p>
      * The size returned by this method does not necessarily represent the
-     * actual raw size (native resolution) of the display.  The returned size may
-     * be adjusted to exclude certain system decor elements that are always visible.
-     * It may also be scaled to provide compatibility with older applications that
+     * actual raw size (native resolution) of the display.
+     * <p>
+     * 1. The returned size may be adjusted to exclude certain system decor elements
+     * that are always visible.
+     * </p><p>
+     * 2. It may be scaled to provide compatibility with older applications that
      * were originally designed for smaller displays.
+     * </p><p>
+     * 3. It can be different depending on the WindowManager to which the display belongs.
+     * <pre>
+     * - If requested from non-Activity context (e.g. Application context via
+     * {@code (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE)})
+     * metrics will report real size of the display based on current rotation.
+     * - If requested from activity resulting metrics will correspond to current window metrics.
+     * In this case the size can be smaller than physical size in multi-window mode.
+     * </pre>
      * </p>
      *
      * @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
@@ -807,7 +827,7 @@
      * The size is adjusted based on the current rotation of the display.
      * </p><p>
      * The real size may be smaller than the physical size of the screen when the
-     * window manager is emulating a smaller display (using adb shell am display-size).
+     * window manager is emulating a smaller display (using adb shell wm size).
      * </p>
      *
      * @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
@@ -816,8 +836,7 @@
         synchronized (this) {
             updateDisplayInfoLocked();
             mDisplayInfo.getLogicalMetrics(outMetrics,
-                    CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO,
-                    mDisplayAdjustments.getConfiguration());
+                    CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
         }
     }
 
@@ -1104,6 +1123,117 @@
     }
 
     /**
+     * Encapsulates the HDR capabilities of a given display.
+     * For example, what HDR types it supports and details about the desired luminance data.
+     * <p>You can get an instance for a given {@link Display} object with
+     * {@link Display#getHdrCapabilities getHdrCapabilities()}.
+     * @hide
+     */
+    public static final class HdrCapabilities implements Parcelable {
+        /**
+         * Invalid luminance value.
+         */
+        public static final float INVALID_LUMINANCE = -1;
+        /**
+         * Dolby Vision high dynamic range (HDR) display.
+         */
+        public static final int HDR_TYPE_DOLBY_VISION = 1;
+        /**
+         * HDR10 display.
+         */
+        public static final int HDR_TYPE_HDR10 = 2;
+        /**
+         * Hybrid Log-Gamma HDR display.
+         */
+        public static final int HDR_TYPE_HLG = 3;
+
+        @IntDef({
+            HDR_TYPE_DOLBY_VISION,
+            HDR_TYPE_HDR10,
+            HDR_TYPE_HLG,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface HdrType {}
+
+        private @HdrType int[] mSupportedHdrTypes = new int[0];
+        private float mMaxLuminance = INVALID_LUMINANCE;
+        private float mMaxAverageLuminance = INVALID_LUMINANCE;
+        private float mMinLuminance = INVALID_LUMINANCE;
+
+        public HdrCapabilities() {
+        }
+
+        /**
+         * Gets the supported HDR types of this display.
+         * Returns empty array if HDR is not supported by the display.
+         */
+        public @HdrType int[] getSupportedHdrTypes() {
+            return mSupportedHdrTypes;
+        }
+        /**
+         * Returns the desired content max luminance data in cd/m2 for this display.
+         */
+        public float getDesiredMaxLuminance() {
+            return mMaxLuminance;
+        }
+        /**
+         * Returns the desired content max frame-average luminance data in cd/m2 for this display.
+         */
+        public float getDesiredMaxAverageLuminance() {
+            return mMaxAverageLuminance;
+        }
+        /**
+         * Returns the desired content min luminance data in cd/m2 for this display.
+         */
+        public float getDesiredMinLuminance() {
+            return mMinLuminance;
+        }
+
+        public static final Creator<HdrCapabilities> CREATOR = new Creator<HdrCapabilities>() {
+            @Override
+            public HdrCapabilities createFromParcel(Parcel source) {
+                return new HdrCapabilities(source);
+            }
+
+            @Override
+            public HdrCapabilities[] newArray(int size) {
+                return new HdrCapabilities[size];
+            }
+        };
+
+        private HdrCapabilities(Parcel source) {
+            readFromParcel(source);
+        }
+
+        public void readFromParcel(Parcel source) {
+            int types = source.readInt();
+            mSupportedHdrTypes = new int[types];
+            for (int i = 0; i < types; ++i) {
+                mSupportedHdrTypes[i] = source.readInt();
+            }
+            mMaxLuminance = source.readFloat();
+            mMaxAverageLuminance = source.readFloat();
+            mMinLuminance = source.readFloat();
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(mSupportedHdrTypes.length);
+            for (int i = 0; i < mSupportedHdrTypes.length; ++i) {
+                dest.writeInt(mSupportedHdrTypes[i]);
+            }
+            dest.writeFloat(mMaxLuminance);
+            dest.writeFloat(mMaxAverageLuminance);
+            dest.writeFloat(mMinLuminance);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+    }
+
+    /**
      * A color transform supported by a given display.
      *
      * @see Display#getSupportedColorTransforms()
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index f912e51..d8b7421 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -193,8 +193,7 @@
     boolean isKeyguardSecure();
     boolean inKeyguardRestrictedInputMode();
     void dismissKeyguard();
-    void keyguardGoingAway(boolean disableWindowAnimations,
-            boolean keyguardGoingToNotificationShade);
+    void keyguardGoingAway(int flags);
 
     void closeSystemDialogs(String reason);
 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 57ab6d4..55393b1 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -84,7 +84,6 @@
 import android.view.AccessibilityIterators.ParagraphTextSegmentIterator;
 import android.view.AccessibilityIterators.TextSegmentIterator;
 import android.view.AccessibilityIterators.WordTextSegmentIterator;
-import android.view.ViewGroup.LayoutParams;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityEventSource;
 import android.view.accessibility.AccessibilityManager;
@@ -10151,19 +10150,6 @@
      *                   {@link #INVISIBLE} or {@link #GONE}.
      */
     protected void onVisibilityChanged(@NonNull View changedView, @Visibility int visibility) {
-        final boolean visible = visibility == VISIBLE && getVisibility() == VISIBLE;
-        if (visible && mAttachInfo != null) {
-            initialAwakenScrollBars();
-        }
-
-        final Drawable dr = mBackground;
-        if (dr != null && visible != dr.isVisible()) {
-            dr.setVisible(visible, false);
-        }
-        final Drawable fg = mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
-        if (fg != null && visible != fg.isVisible()) {
-            fg.setVisible(visible, false);
-        }
     }
 
     /**
@@ -10220,6 +10206,52 @@
     }
 
     /**
+     * Internal dispatching method for {@link #onVisibilityAggregated}. Overridden by
+     * ViewGroup. Intended to only be called when {@link #isAttachedToWindow()},
+     * {@link #getWindowVisibility()} is {@link #VISIBLE} and this view's parent {@link #isShown()}.
+     *
+     * @param changedView the view that changed, either <code>this</code> or an ancestor
+     * @param visibility aggregated visibility of this view's parent or changedView, whichever
+     *                   is closer
+     * @return the aggregated visibility for this view
+     */
+    int dispatchVisibilityAggregated(View changedView, @Visibility int visibility) {
+        visibility = Math.max(visibility, getVisibility());
+        onVisibilityAggregated(changedView, visibility);
+        return visibility;
+    }
+
+    /**
+     * Called when the user-visibility of this View is potentially affected by a change
+     * to this view itself, an ancestor view or the window this view is attached to.
+     *
+     * <p>The visibility value reported will be one of {@link #VISIBLE}, {@link #INVISIBLE}
+     * or {@link #GONE}, reflecting this view's aggregated visibility within its window.
+     * The visibility parameter takes this view's own visibility into account.
+     * Calls to this method may be repeated with the same visibility values; implementations
+     * should ensure that work done is not duplicated unnecessarily.</p>
+     *
+     * @param changedView the view that changed; may be <code>this</code> or an ancestor
+     * @param visibility the visibility of this view in the context of the full window
+     */
+    @CallSuper
+    public void onVisibilityAggregated(View changedView, @Visibility int visibility) {
+        final boolean visible = visibility == VISIBLE && getVisibility() == VISIBLE;
+        if (visible && mAttachInfo != null) {
+            initialAwakenScrollBars();
+        }
+
+        final Drawable dr = mBackground;
+        if (dr != null && visible != dr.isVisible()) {
+            dr.setVisible(visible, false);
+        }
+        final Drawable fg = mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
+        if (fg != null && visible != fg.isVisible()) {
+            fg.setVisible(visible, false);
+        }
+    }
+
+    /**
      * Returns the current visibility of the window this view is attached to
      * (either {@link #GONE}, {@link #INVISIBLE}, or {@link #VISIBLE}).
      *
@@ -11336,6 +11368,16 @@
 
             if (mAttachInfo != null) {
                 dispatchVisibilityChanged(this, newVisibility);
+
+                // Aggregated visibility changes are dispatched to attached views
+                // in visible windows where the parent is currently shown/drawn
+                // or the parent is not a ViewGroup (and therefore assumed to be a ViewRoot),
+                // discounting clipping or overlapping. This makes it a good place
+                // to change animation states.
+                if (mParent != null && getWindowVisibility() == VISIBLE &&
+                        ((!(mParent instanceof ViewGroup)) || ((ViewGroup) mParent).isShown())) {
+                    dispatchVisibilityAggregated(this, newVisibility);
+                }
                 notifySubtreeAccessibilityStateChangedIfNeeded();
             }
         }
@@ -15246,6 +15288,9 @@
         int vis = info.mWindowVisibility;
         if (vis != GONE) {
             onWindowVisibilityChanged(vis);
+            if (isShown()) {
+                onVisibilityAggregated(this, vis);
+            }
         }
 
         // Send onVisibilityChanged directly instead of dispatchVisibilityChanged.
@@ -15266,6 +15311,9 @@
             int vis = info.mWindowVisibility;
             if (vis != GONE) {
                 onWindowVisibilityChanged(GONE);
+                if (isShown()) {
+                    onVisibilityAggregated(this, GONE);
+                }
             }
         }
 
@@ -17958,6 +18006,7 @@
         if (mBackground != null) {
             mBackground.setCallback(null);
             unscheduleDrawable(mBackground);
+            mBackground.setVisible(false, false);
         }
 
         if (background != null) {
@@ -17998,7 +18047,7 @@
             if (background.isStateful()) {
                 background.setState(getDrawableState());
             }
-            background.setVisible(getVisibility() == VISIBLE, false);
+            background.setVisible(getWindowVisibility() == VISIBLE && isShown(), false);
             mBackground = background;
 
             applyBackgroundTint();
@@ -18180,6 +18229,7 @@
         if (mForegroundInfo.mDrawable != null) {
             mForegroundInfo.mDrawable.setCallback(null);
             unscheduleDrawable(mForegroundInfo.mDrawable);
+            mForegroundInfo.mDrawable.setVisible(false, false);
         }
 
         mForegroundInfo.mDrawable = foreground;
@@ -18194,6 +18244,7 @@
                 foreground.setState(getDrawableState());
             }
             applyForegroundTint();
+            foreground.setVisible(getWindowVisibility() == VISIBLE && isShown(), false);
         } else if ((mViewFlags & WILL_NOT_DRAW) != 0 && mBackground == null) {
             mPrivateFlags |= PFLAG_SKIP_DRAW;
         }
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 56ee478..36a5db1 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1291,6 +1291,23 @@
     }
 
     @Override
+    int dispatchVisibilityAggregated(View changedView, @Visibility int visibility) {
+        visibility = super.dispatchVisibilityAggregated(changedView, visibility);
+        final int count = mChildrenCount;
+        final View[] children = mChildren;
+        for (int i = 0; i < count; i++) {
+            // Only dispatch to children with at least the same level of visibility
+            // that we're reporting, otherwise it won't affect that child/subtree at all
+            // so it's not worth telling them about it. Note that we use <= here
+            // because VISIBLE < INVISIBLE < GONE as constant values.
+            if (children[i].getVisibility() <= visibility) {
+                children[i].dispatchVisibilityAggregated(changedView, visibility);
+            }
+        }
+        return visibility;
+    }
+
+    @Override
     public void dispatchConfigurationChanged(Configuration newConfig) {
         super.dispatchConfigurationChanged(newConfig);
         final int count = mChildrenCount;
diff --git a/core/java/android/view/ViewOverlay.java b/core/java/android/view/ViewOverlay.java
index 69c30ba..b770bd5 100644
--- a/core/java/android/view/ViewOverlay.java
+++ b/core/java/android/view/ViewOverlay.java
@@ -216,6 +216,9 @@
         public void clear() {
             removeAllViews();
             if (mDrawables != null) {
+                for (Drawable drawable : mDrawables) {
+                    drawable.setCallback(null);
+                }
                 mDrawables.clear();
             }
         }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index f7405e2..fecf892 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1472,6 +1472,7 @@
         if (viewVisibilityChanged) {
             mAttachInfo.mWindowVisibility = viewVisibility;
             host.dispatchWindowVisibilityChanged(viewVisibility);
+            host.dispatchVisibilityAggregated(host, viewVisibility);
             if (viewVisibility != View.VISIBLE || mNewSurfaceNeeded) {
                 endDragResizing();
                 destroyHardwareResources();
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index b011414..c1392fe 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -91,6 +91,11 @@
     public final static int FLAG_INTERACTIVE = 0x20000000;
     public final static int FLAG_PASS_TO_USER = 0x40000000;
 
+    // Flags for IActivityManager.keyguardGoingAway()
+    public final static int KEYGUARD_GOING_AWAY_FLAG_TO_SHADE = 1 << 0;
+    public final static int KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS = 1 << 1;
+    public final static int KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER = 1 << 2;
+
     // Flags used for indicating whether the internal and/or external input devices
     // of some type are available.
     public final static int PRESENCE_INTERNAL = 1 << 0;
@@ -405,6 +410,12 @@
          *         not attached to any stack.
          */
         int getStackId();
+
+        /**
+         * Returns true if the window is current in multi-windowing mode. i.e. it shares the
+         * screen with other application windows.
+         */
+        public boolean inMultiWindowMode();
     }
 
     /**
diff --git a/core/java/android/view/animation/BaseInterpolator.java b/core/java/android/view/animation/BaseInterpolator.java
index 9c0014c..a78fa1e 100644
--- a/core/java/android/view/animation/BaseInterpolator.java
+++ b/core/java/android/view/animation/BaseInterpolator.java
@@ -16,22 +16,24 @@
 
 package android.view.animation;
 
+import android.content.pm.ActivityInfo.Config;
+
 /**
  * An abstract class which is extended by default interpolators.
  */
 abstract public class BaseInterpolator implements Interpolator {
-    private int mChangingConfiguration;
+    private @Config int mChangingConfiguration;
     /**
      * @hide
      */
-    public int getChangingConfiguration() {
+    public @Config int getChangingConfiguration() {
         return mChangingConfiguration;
     }
 
     /**
      * @hide
      */
-    void setChangingConfiguration(int changingConfiguration) {
+    void setChangingConfiguration(@Config int changingConfiguration) {
         mChangingConfiguration = changingConfiguration;
     }
 }
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 3b6ba3a..4bcb406 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -18,6 +18,7 @@
 
 import android.R;
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
@@ -216,6 +217,7 @@
     boolean mInBatchEditControllers;
     boolean mShowSoftInputOnFocus = true;
     private boolean mPreserveSelection;
+    private boolean mRestartActionModeOnNextRefresh;
     boolean mTemporaryDetach;
 
     boolean mIsBeingLongClicked;
@@ -380,9 +382,8 @@
         updateSpellCheckSpans(0, mTextView.getText().length(),
                 true /* create the spell checker if needed */);
 
-        if (mTextView.getSelectionStart() != mTextView.getSelectionEnd()) {
-            // We had an active selection from before, start the selection mode.
-            startSelectionActionMode();
+        if (mTextView.hasSelection()) {
+            refreshTextActionMode();
         }
 
         getPositionListener().addSubscriber(mCursorAnchorInfoNotifier, true);
@@ -1081,6 +1082,10 @@
     }
 
     private void startDragAndDrop() {
+        // TODO: Fix drag and drop in full screen extracted mode.
+        if (mTextView.isInExtractedMode()) {
+            return;
+        }
         final int start = mTextView.getSelectionStart();
         final int end = mTextView.getSelectionEnd();
         CharSequence selectedText = mTextView.getTransformedText(start, end);
@@ -1283,7 +1288,7 @@
             }
             final InputMethodManager imm = InputMethodManager.peekInstance();
             if (mTextView.hasSelection() && !extractedTextModeWillBeStarted()) {
-                startSelectionActionMode();
+                refreshTextActionMode();
             }
         } else {
             if (mBlink != null) {
@@ -1846,6 +1851,7 @@
 
     void refreshTextActionMode() {
         if (extractedTextModeWillBeStarted()) {
+            mRestartActionModeOnNextRefresh = false;
             return;
         }
         final boolean hasSelection = mTextView.hasSelection();
@@ -1854,12 +1860,19 @@
         if ((selectionController != null && selectionController.isCursorBeingModified())
                 || (insertionController != null && insertionController.isCursorBeingModified())) {
             // ActionMode should be managed by the currently active cursor controller.
+            mRestartActionModeOnNextRefresh = false;
             return;
         }
         if (hasSelection) {
-            if (mTextActionMode == null || selectionController == null
-                    || !selectionController.isActive()) {
-                // Avoid dismissing the selection if it exists.
+            hideInsertionPointCursorController();
+            if (mTextActionMode == null) {
+                if (mRestartActionModeOnNextRefresh || mTextView.isInExtractedMode()) {
+                    // To avoid distraction, newly start action mode only when selection action
+                    // mode is being restarted or in full screen extracted mode.
+                    startSelectionActionMode();
+                }
+            } else if (selectionController == null || !selectionController.isActive()) {
+                // Insertion action mode is active. Avoid dismissing the selection.
                 stopTextActionModeWithPreservingSelection();
                 startSelectionActionMode();
             } else {
@@ -1874,6 +1887,7 @@
                 mTextActionMode.invalidateContentRect();
             }
         }
+        mRestartActionModeOnNextRefresh = false;
     }
 
     /**
@@ -1904,11 +1918,12 @@
      *
      * @return true if the selection mode was actually started.
      */
-    private boolean startSelectionActionMode() {
+    boolean startSelectionActionMode() {
         boolean selectionStarted = startSelectionActionModeInternal();
         if (selectionStarted) {
             getSelectionController().show();
         }
+        mRestartActionModeOnNextRefresh = false;
         return selectionStarted;
     }
 
@@ -2112,6 +2127,9 @@
     }
 
     private void stopTextActionModeWithPreservingSelection() {
+        if (mTextActionMode != null) {
+            mRestartActionModeOnNextRefresh = true;
+        }
         mPreserveSelection = true;
         stopTextActionMode();
         mPreserveSelection = false;
@@ -2460,7 +2478,7 @@
             }
             final SubMenu subMenu = menu.addSubMenu(Menu.NONE, Menu.NONE, MENU_ITEM_ORDER_REPLACE,
                     com.android.internal.R.string.replace);
-            final int numItems = mSuggestionHelper.getSuggestionInfo(suggestionInfoArray);
+            final int numItems = mSuggestionHelper.getSuggestionInfo(suggestionInfoArray, null);
             for (int i = 0; i < numItems; i++) {
                 final SuggestionInfo info = suggestionInfoArray[i];
                 subMenu.add(Menu.NONE, Menu.NONE, i, info.mText)
@@ -2516,32 +2534,44 @@
         mPreserveSelection = true;
     }
 
-    private void replaceWithSuggestion(final SuggestionInfo suggestionInfo) {
+    @Nullable
+    private SuggestionSpan findEquivalentSuggestionSpan(
+            @NonNull SuggestionSpanInfo suggestionSpanInfo) {
         final Editable editable = (Editable) mTextView.getText();
-        if (editable.getSpanStart(suggestionInfo.mSuggestionSpan) < 0) {
-            // Suggestion span coundn't be found. Try to find a suggestion span that has the same
-            // contents.
-            final SuggestionSpan[] suggestionSpans = editable.getSpans(
-                    suggestionInfo.mSuggestionSpanStart, suggestionInfo.mSuggestionSpanEnd,
-                    SuggestionSpan.class);
-            for (final SuggestionSpan suggestionSpan : suggestionSpans) {
-                final int spanStart = editable.getSpanStart(suggestionSpan);
-                if (spanStart != suggestionInfo.mSuggestionSpanStart) {
-                    continue;
-                }
-                int spanEnd = editable.getSpanEnd(suggestionSpan);
-                if (spanEnd != suggestionInfo.mSuggestionSpanEnd) {
-                    continue;
-                }
-                if (suggestionSpan.equals(suggestionInfo.mSuggestionSpan)) {
-                    // Found.
-                    suggestionInfo.mSuggestionSpan = suggestionSpan;
-                    break;
-                }
+        if (editable.getSpanStart(suggestionSpanInfo.mSuggestionSpan) >= 0) {
+            // Exactly same span is found.
+            return suggestionSpanInfo.mSuggestionSpan;
+        }
+        // Suggestion span couldn't be found. Try to find a suggestion span that has the same
+        // contents.
+        final SuggestionSpan[] suggestionSpans = editable.getSpans(suggestionSpanInfo.mSpanStart,
+                suggestionSpanInfo.mSpanEnd, SuggestionSpan.class);
+        for (final SuggestionSpan suggestionSpan : suggestionSpans) {
+            final int start = editable.getSpanStart(suggestionSpan);
+            if (start != suggestionSpanInfo.mSpanStart) {
+                continue;
+            }
+            final int end = editable.getSpanEnd(suggestionSpan);
+            if (end != suggestionSpanInfo.mSpanEnd) {
+                continue;
+            }
+            if (suggestionSpan.equals(suggestionSpanInfo.mSuggestionSpan)) {
+                return suggestionSpan;
             }
         }
-        final int spanStart = editable.getSpanStart(suggestionInfo.mSuggestionSpan);
-        final int spanEnd = editable.getSpanEnd(suggestionInfo.mSuggestionSpan);
+        return null;
+    }
+
+    private void replaceWithSuggestion(@NonNull final SuggestionInfo suggestionInfo) {
+        final SuggestionSpan targetSuggestionSpan = findEquivalentSuggestionSpan(
+                suggestionInfo.mSuggestionSpanInfo);
+        if (targetSuggestionSpan == null) {
+            // Span has been removed
+            return;
+        }
+        final Editable editable = (Editable) mTextView.getText();
+        final int spanStart = editable.getSpanStart(targetSuggestionSpan);
+        final int spanEnd = editable.getSpanEnd(targetSuggestionSpan);
         if (spanStart < 0 || spanEnd <= spanStart) {
             // Span has been removed
             return;
@@ -2571,7 +2601,7 @@
         }
 
         // Notify source IME of the suggestion pick. Do this before swapping texts.
-        suggestionInfo.mSuggestionSpan.notifySelection(
+        targetSuggestionSpan.notifySelection(
                 mTextView.getContext(), originalText, suggestionInfo.mSuggestionIndex);
 
         // Swap text content between actual text and Suggestion span
@@ -2581,7 +2611,7 @@
                 suggestionStart, suggestionEnd).toString();
         mTextView.replaceText_internal(spanStart, spanEnd, suggestion);
 
-        String[] suggestions = suggestionInfo.mSuggestionSpan.getSuggestions();
+        String[] suggestions = targetSuggestionSpan.getSuggestions();
         suggestions[suggestionInfo.mSuggestionIndex] = originalText;
 
         // Restore previous SuggestionSpans
@@ -3029,19 +3059,12 @@
         }
     }
 
-    private static class SuggestionInfo {
+    private static final class SuggestionInfo {
         // Range of actual suggestion within mText
         int mSuggestionStart, mSuggestionEnd;
 
         // The SuggestionSpan that this TextView represents
-        @Nullable
-        SuggestionSpan mSuggestionSpan;
-
-        // The SuggestionSpan start position
-        int mSuggestionSpanStart;
-
-        // The SuggestionSpan end position
-        int mSuggestionSpanEnd;
+        final SuggestionSpanInfo mSuggestionSpanInfo = new SuggestionSpanInfo();
 
         // The index of this suggestion inside suggestionSpan
         int mSuggestionIndex;
@@ -3049,9 +3072,32 @@
         final SpannableStringBuilder mText = new SpannableStringBuilder();
 
         void clear() {
-            mSuggestionSpan = null;
+            mSuggestionSpanInfo.clear();
             mText.clear();
         }
+
+        // Utility method to set attributes about a SuggestionSpan.
+        void setSpanInfo(SuggestionSpan span, int spanStart, int spanEnd) {
+            mSuggestionSpanInfo.mSuggestionSpan = span;
+            mSuggestionSpanInfo.mSpanStart = spanStart;
+            mSuggestionSpanInfo.mSpanEnd = spanEnd;
+        }
+    }
+
+    private static final class SuggestionSpanInfo {
+        // The SuggestionSpan;
+        @Nullable
+        SuggestionSpan mSuggestionSpan;
+
+        // The SuggestionSpan start position
+        int mSpanStart;
+
+        // The SuggestionSpan end position
+        int mSpanEnd;
+
+        void clear() {
+            mSuggestionSpan = null;
+        }
     }
 
     private class SuggestionHelper {
@@ -3109,48 +3155,51 @@
          * position.
          *
          * @param suggestionInfos SuggestionInfo array the results will be set.
+         * @param misspelledSpanInfo a struct the misspelled SuggestionSpan info will be set.
          * @return the number of suggestions actually fetched.
          */
-        public int getSuggestionInfo(SuggestionInfo[] suggestionInfos) {
+        public int getSuggestionInfo(SuggestionInfo[] suggestionInfos,
+                @Nullable SuggestionSpanInfo misspelledSpanInfo) {
             final Spannable spannable = (Spannable) mTextView.getText();
             final SuggestionSpan[] suggestionSpans = getSortedSuggestionSpans();
             final int nbSpans = suggestionSpans.length;
             if (nbSpans == 0) return 0;
 
             int numberOfSuggestions = 0;
-            for (int spanIndex = 0; spanIndex < nbSpans; spanIndex++) {
-                final SuggestionSpan suggestionSpan = suggestionSpans[spanIndex];
+            for (final SuggestionSpan suggestionSpan : suggestionSpans) {
                 final int spanStart = spannable.getSpanStart(suggestionSpan);
                 final int spanEnd = spannable.getSpanEnd(suggestionSpan);
 
+                if (misspelledSpanInfo != null
+                        && (suggestionSpan.getFlags() & SuggestionSpan.FLAG_MISSPELLED) != 0) {
+                    misspelledSpanInfo.mSuggestionSpan = suggestionSpan;
+                    misspelledSpanInfo.mSpanStart = spanStart;
+                    misspelledSpanInfo.mSpanEnd = spanEnd;
+                }
+
                 final String[] suggestions = suggestionSpan.getSuggestions();
                 final int nbSuggestions = suggestions.length;
+                suggestionLoop:
                 for (int suggestionIndex = 0; suggestionIndex < nbSuggestions; suggestionIndex++) {
                     final String suggestion = suggestions[suggestionIndex];
-                    boolean suggestionIsDuplicate = false;
                     for (int i = 0; i < numberOfSuggestions; i++) {
-                        if (suggestionInfos[i].mText.toString().equals(suggestion)) {
-                            final SuggestionSpan otherSuggestionSpan =
-                                    suggestionInfos[i].mSuggestionSpan;
-                            final int otherSpanStart = spannable.getSpanStart(otherSuggestionSpan);
-                            final int otherSpanEnd = spannable.getSpanEnd(otherSuggestionSpan);
+                        final SuggestionInfo otherSuggestionInfo = suggestionInfos[i];
+                        if (otherSuggestionInfo.mText.toString().equals(suggestion)) {
+                            final int otherSpanStart =
+                                    otherSuggestionInfo.mSuggestionSpanInfo.mSpanStart;
+                            final int otherSpanEnd =
+                                    otherSuggestionInfo.mSuggestionSpanInfo.mSpanEnd;
                             if (spanStart == otherSpanStart && spanEnd == otherSpanEnd) {
-                                suggestionIsDuplicate = true;
-                                break;
+                                continue suggestionLoop;
                             }
                         }
                     }
 
-                    if (suggestionIsDuplicate) {
-                        continue;
-                    }
                     SuggestionInfo suggestionInfo = suggestionInfos[numberOfSuggestions];
-                    suggestionInfo.mSuggestionSpan = suggestionSpan;
+                    suggestionInfo.setSpanInfo(suggestionSpan, spanStart, spanEnd);
                     suggestionInfo.mSuggestionIndex = suggestionIndex;
                     suggestionInfo.mSuggestionStart = 0;
                     suggestionInfo.mSuggestionEnd = suggestion.length();
-                    suggestionInfo.mSuggestionSpanStart = spanStart;
-                    suggestionInfo.mSuggestionSpanEnd = spanEnd;
                     suggestionInfo.mText.replace(0, suggestionInfo.mText.length(), suggestion);
                     numberOfSuggestions++;
                     if (numberOfSuggestions >= suggestionInfos.length) {
@@ -3180,7 +3229,7 @@
         private TextView mAddToDictionaryButton;
         private TextView mDeleteButton;
         private ListView mSuggestionListView;
-        private SuggestionSpan mMisspelledSpan;
+        private final SuggestionSpanInfo mMisspelledSpanInfo = new SuggestionSpanInfo();
         private int mContainerMarginWidth;
         private int mContainerMarginTop;
 
@@ -3252,9 +3301,18 @@
                     com.android.internal.R.id.addToDictionaryButton);
             mAddToDictionaryButton.setOnClickListener(new View.OnClickListener() {
                 public void onClick(View v) {
+                    final SuggestionSpan misspelledSpan =
+                            findEquivalentSuggestionSpan(mMisspelledSpanInfo);
+                    if (misspelledSpan == null) {
+                        // Span has been removed.
+                        return;
+                    }
                     final Editable editable = (Editable) mTextView.getText();
-                    final int spanStart = editable.getSpanStart(mMisspelledSpan);
-                    final int spanEnd = editable.getSpanEnd(mMisspelledSpan);
+                    final int spanStart = editable.getSpanStart(misspelledSpan);
+                    final int spanEnd = editable.getSpanEnd(misspelledSpan);
+                    if (spanStart < 0 || spanEnd <= spanStart) {
+                        return;
+                    }
                     final String originalText = TextUtils.substring(editable, spanStart, spanEnd);
 
                     final Intent intent = new Intent(Settings.ACTION_USER_DICTIONARY_INSERT);
@@ -3265,7 +3323,7 @@
                     mTextView.getContext().startActivity(intent);
                     // There is no way to know if the word was indeed added. Re-check.
                     // TODO The ExtractEditText should remove the span in the original text instead
-                    editable.removeSpan(mMisspelledSpan);
+                    editable.removeSpan(mMisspelledSpanInfo.mSuggestionSpan);
                     Selection.setSelection(editable, spanEnd);
                     updateSpellCheckSpans(spanStart, spanEnd, false);
                     hideWithCleanUp();
@@ -3422,30 +3480,29 @@
             for (final SuggestionInfo info : mSuggestionInfos) {
                 info.clear();
             }
-            mMisspelledSpan = null;
+            mMisspelledSpanInfo.clear();
             hide();
         }
 
         private boolean updateSuggestions() {
             Spannable spannable = (Spannable) mTextView.getText();
             mNumberOfSuggestions =
-                    mSuggestionHelper.getSuggestionInfo(mSuggestionInfos);
-            if (mNumberOfSuggestions == 0) {
+                    mSuggestionHelper.getSuggestionInfo(mSuggestionInfos, mMisspelledSpanInfo);
+            if (mNumberOfSuggestions == 0 && mMisspelledSpanInfo.mSuggestionSpan == null) {
                 return false;
             }
 
             int spanUnionStart = mTextView.getText().length();
             int spanUnionEnd = 0;
 
-            mMisspelledSpan = null;
             for (int i = 0; i < mNumberOfSuggestions; i++) {
-                final SuggestionInfo suggestionInfo = mSuggestionInfos[i];
-                final SuggestionSpan suggestionSpan = suggestionInfo.mSuggestionSpan;
-                if ((suggestionSpan.getFlags() & SuggestionSpan.FLAG_MISSPELLED) != 0) {
-                    mMisspelledSpan = suggestionSpan;
-                }
-                spanUnionStart = Math.min(spanUnionStart, suggestionInfo.mSuggestionSpanStart);
-                spanUnionEnd = Math.max(spanUnionEnd, suggestionInfo.mSuggestionSpanEnd);
+                final SuggestionSpanInfo spanInfo = mSuggestionInfos[i].mSuggestionSpanInfo;
+                spanUnionStart = Math.min(spanUnionStart, spanInfo.mSpanStart);
+                spanUnionEnd = Math.max(spanUnionEnd, spanInfo.mSpanEnd);
+            }
+            if (mMisspelledSpanInfo.mSuggestionSpan != null) {
+                spanUnionStart = Math.min(spanUnionStart, mMisspelledSpanInfo.mSpanStart);
+                spanUnionEnd = Math.max(spanUnionEnd, mMisspelledSpanInfo.mSpanEnd);
             }
 
             for (int i = 0; i < mNumberOfSuggestions; i++) {
@@ -3454,17 +3511,23 @@
 
             // Make "Add to dictionary" item visible if there is a span with the misspelled flag
             int addToDictionaryButtonVisibility = View.GONE;
-            if (mMisspelledSpan != null) {
-                final int misspelledStart = spannable.getSpanStart(mMisspelledSpan);
-                final int misspelledEnd = spannable.getSpanEnd(mMisspelledSpan);
-                if (misspelledStart >= 0 && misspelledEnd > misspelledStart) {
+            if (mMisspelledSpanInfo.mSuggestionSpan != null) {
+                if (mMisspelledSpanInfo.mSpanStart >= 0
+                        && mMisspelledSpanInfo.mSpanEnd > mMisspelledSpanInfo.mSpanStart) {
                     addToDictionaryButtonVisibility = View.VISIBLE;
                 }
             }
             mAddToDictionaryButton.setVisibility(addToDictionaryButtonVisibility);
 
             if (mSuggestionRangeSpan == null) mSuggestionRangeSpan = new SuggestionRangeSpan();
-            final int underlineColor = mSuggestionInfos[0].mSuggestionSpan.getUnderlineColor();
+            final int underlineColor;
+            if (mNumberOfSuggestions != 0) {
+                underlineColor =
+                        mSuggestionInfos[0].mSuggestionSpanInfo.mSuggestionSpan.getUnderlineColor();
+            } else {
+                underlineColor = mMisspelledSpanInfo.mSuggestionSpan.getUnderlineColor();
+            }
+
             if (underlineColor == 0) {
                 // Fallback on the default highlight color when the first span does not provide one
                 mSuggestionRangeSpan.setBackgroundColor(mTextView.mHighlightColor);
@@ -3484,8 +3547,8 @@
         private void highlightTextDifferences(SuggestionInfo suggestionInfo, int unionStart,
                 int unionEnd) {
             final Spannable text = (Spannable) mTextView.getText();
-            final int spanStart = suggestionInfo.mSuggestionSpanStart;
-            final int spanEnd = suggestionInfo.mSuggestionSpanEnd;
+            final int spanStart = suggestionInfo.mSuggestionSpanInfo.mSpanStart;
+            final int spanEnd = suggestionInfo.mSuggestionSpanInfo.mSpanEnd;
 
             // Adjust the start/end of the suggestion span
             suggestionInfo.mSuggestionStart = spanStart - unionStart;
@@ -3661,6 +3724,8 @@
 
         @Override
         public void onDestroyActionMode(ActionMode mode) {
+            // Clear mTextActionMode not to recursively destroy action mode by clearing selection.
+            mTextActionMode = null;
             Callback customCallback = getCustomCallback();
             if (customCallback != null) {
                 customCallback.onDestroyActionMode(mode);
@@ -3679,8 +3744,6 @@
             if (mSelectionModifierCursorController != null) {
                 mSelectionModifierCursorController.hide();
             }
-
-            mTextActionMode = null;
         }
 
         @Override
@@ -5083,27 +5146,12 @@
                     // No longer dragging to select text, let the parent intercept events.
                     mTextView.getParent().requestDisallowInterceptTouchEvent(false);
 
-                    int startOffset = mTextView.getSelectionStart();
-                    int endOffset = mTextView.getSelectionEnd();
-
-                    // Since we don't let drag handles pass once they're visible, we need to
-                    // make sure the start / end locations are correct because the user *can*
-                    // switch directions during the initial drag.
-                    if (endOffset < startOffset) {
-                        int tmp = endOffset;
-                        endOffset = startOffset;
-                        startOffset = tmp;
-
-                        // Also update the selection with the right offsets in this case.
-                        Selection.setSelection((Spannable) mTextView.getText(),
-                                startOffset, endOffset);
-                    }
-                    if (startOffset != endOffset) {
-                        startSelectionActionMode();
-                    }
-
                     // No longer the first dragging motion, reset.
                     resetDragAcceleratorState();
+
+                    if (mTextView.hasSelection()) {
+                        startSelectionActionMode();
+                    }
                     break;
             }
         }
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 3400873..71b5ce9 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -913,6 +913,7 @@
         if (mDrawable != null) {
             mDrawable.setCallback(null);
             unscheduleDrawable(mDrawable);
+            mDrawable.setVisible(false, false);
         }
 
         mDrawable = d;
@@ -923,7 +924,8 @@
             if (d.isStateful()) {
                 d.setState(getDrawableState());
             }
-            d.setVisible(getVisibility() == VISIBLE, true);
+            d.setVisible(isAttachedToWindow() && getWindowVisibility() == VISIBLE && isShown(),
+                    true);
             d.setLevel(mLevel);
             mDrawableWidth = d.getIntrinsicWidth();
             mDrawableHeight = d.getIntrinsicHeight();
@@ -1498,32 +1500,15 @@
         }
     }
 
-    @RemotableViewMethod
     @Override
-    public void setVisibility(int visibility) {
-        super.setVisibility(visibility);
+    public void onVisibilityAggregated(View changedView, @Visibility int visibility) {
+        super.onVisibilityAggregated(changedView, visibility);
         if (mDrawable != null) {
             mDrawable.setVisible(visibility == VISIBLE, false);
         }
     }
 
     @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        if (mDrawable != null) {
-            mDrawable.setVisible(getVisibility() == VISIBLE, false);
-        }
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        if (mDrawable != null) {
-            mDrawable.setVisible(false, false);
-        }
-    }
-
-    @Override
     public CharSequence getAccessibilityClassName() {
         return ImageView.class.getName();
     }
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index ce94870..dd0f91e 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -246,6 +246,8 @@
 
     boolean mMirrorForRtl = false;
 
+    private boolean mAggregatedIsVisible;
+
     private final ArrayList<RefreshData> mRefreshData = new ArrayList<RefreshData>();
 
     private AccessibilityEventSender mAccessibilityEventSender;
@@ -620,9 +622,7 @@
                 oldDrawable.setVisible(false, false);
             }
             if (mCurrentDrawable != null) {
-                mCurrentDrawable.setVisible(
-                        getVisibility() == VISIBLE && getWindowVisibility() == VISIBLE,
-                        false);
+                mCurrentDrawable.setVisible(getWindowVisibility() == VISIBLE && isShown(), false);
             }
         }
     }
@@ -1645,50 +1645,26 @@
     }
 
     @Override
-    @RemotableViewMethod
-    public void setVisibility(int v) {
-        if (getVisibility() != v) {
-            super.setVisibility(v);
+    public void onVisibilityAggregated(View changedView, @Visibility int visibility) {
+        super.onVisibilityAggregated(changedView, visibility);
+
+        final boolean isVisible = visibility == VISIBLE;
+        if (isVisible != mAggregatedIsVisible) {
+            mAggregatedIsVisible = isVisible;
 
             if (mIndeterminate) {
                 // let's be nice with the UI thread
-                if (v == GONE || v == INVISIBLE) {
-                    stopAnimation();
-                } else {
+                if (isVisible) {
                     startAnimation();
+                } else {
+                    stopAnimation();
                 }
             }
-        }
-    }
 
-    @Override
-    protected void onVisibilityChanged(View changedView, int visibility) {
-        super.onVisibilityChanged(changedView, visibility);
-
-        updateVisibility();
-    }
-
-    @Override
-    protected void onWindowVisibilityChanged(@Visibility int visibility) {
-        super.onWindowVisibilityChanged(visibility);
-
-        updateVisibility();
-    }
-
-    private void updateVisibility() {
-        final boolean isVisible = getVisibility() == VISIBLE && getWindowVisibility() == VISIBLE;
-        if (mIndeterminate) {
-            // let's be nice with the UI thread
-            if (isVisible) {
-                startAnimation();
-            } else {
-                stopAnimation();
+            if (mCurrentDrawable != null) {
+                mCurrentDrawable.setVisible(isVisible, false);
             }
         }
-
-        if (mCurrentDrawable != null) {
-            mCurrentDrawable.setVisible(isVisible, false);
-        }
     }
 
     @Override
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index e971f86..fbedbda 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -9212,6 +9212,10 @@
                     }
                     if (start >= 0 && start <= end && end <= text.length()) {
                         Selection.setSelection((Spannable) text, start, end);
+                        // Make sure selection mode is engaged.
+                        if (mEditor != null) {
+                            mEditor.startSelectionActionMode();
+                        }
                         return true;
                     }
                 }
diff --git a/core/java/com/android/internal/app/UnlaunchableAppActivity.java b/core/java/com/android/internal/app/UnlaunchableAppActivity.java
index 29190f9..f6fbaab 100644
--- a/core/java/com/android/internal/app/UnlaunchableAppActivity.java
+++ b/core/java/com/android/internal/app/UnlaunchableAppActivity.java
@@ -42,15 +42,13 @@
 
 /**
  * A dialog shown to the user when they try to launch an app from a quiet profile
- * ({@link UserManager#isQuietModeEnabled(UserHandle)}, or when the app is suspended by the
- * profile owner or device owner.
+ * ({@link UserManager#isQuietModeEnabled(UserHandle)}.
  */
 public class UnlaunchableAppActivity extends Activity
         implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener {
     private static final String TAG = "UnlaunchableAppActivity";
 
     private static final int UNLAUNCHABLE_REASON_QUIET_MODE = 1;
-    private static final int UNLAUNCHABLE_REASON_SUSPENDED_PACKAGE = 2;
     private static final String EXTRA_UNLAUNCHABLE_REASON = "unlaunchable_reason";
 
     private int mUserId;
@@ -74,37 +72,6 @@
         if (mReason == UNLAUNCHABLE_REASON_QUIET_MODE) {
             dialogTitle = getResources().getString(R.string.work_mode_off_title);
             dialogMessage = getResources().getString(R.string.work_mode_off_message);
-        } else if (mReason == UNLAUNCHABLE_REASON_SUSPENDED_PACKAGE) {
-            DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(
-                    Context.DEVICE_POLICY_SERVICE);
-            String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
-            String packageLabel = packageName;
-            try {
-                Context userContext = createPackageContextAsUser(packageName, 0,
-                        UserHandle.of(mUserId));
-                ApplicationInfo appInfo = userContext.getApplicationInfo();
-                if (appInfo != null) {
-                    packageLabel = userContext.getPackageManager().getApplicationLabel(appInfo)
-                            .toString();
-                }
-            } catch (NameNotFoundException e) {
-            }
-            dialogTitle = String.format(getResources().getString(R.string.suspended_package_title),
-                    packageLabel);
-            ComponentName profileOwner = dpm.getProfileOwnerAsUser(mUserId);
-            String profileOwnerName = null;
-            if (profileOwner != null) {
-                dialogMessage = dpm.getShortSupportMessageForUser(profileOwner, mUserId);
-                profileOwnerName = dpm.getProfileOwnerNameAsUser(mUserId);
-            }
-            // Fall back to standard message if profile owner hasn't set something specific.
-            if (TextUtils.isEmpty(dialogMessage)) {
-                if (TextUtils.isEmpty(profileOwnerName)) {
-                    profileOwnerName = getResources().getString(R.string.unknownName);
-                }
-                dialogMessage = getResources().getString(R.string.suspended_package_message,
-                        profileOwnerName);
-            }
         } else {
             Log.wtf(TAG, "Invalid unlaunchable type: " + mReason);
             finish();
@@ -154,12 +121,4 @@
         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
         return intent;
     }
-
-    public static Intent createPackageSuspendedDialogIntent(String packageName, int userId) {
-        Intent intent = createBaseIntent();
-        intent.putExtra(EXTRA_UNLAUNCHABLE_REASON, UNLAUNCHABLE_REASON_SUSPENDED_PACKAGE);
-        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
-        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
-        return intent;
-    }
 }
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 2a04526..798a6de 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -1184,8 +1184,7 @@
     void** args = (void**) malloc(3 * sizeof(void*));   // javaThreadShell must free
     int result;
 
-    if (!threadName)
-        threadName = "unnamed thread";
+    LOG_ALWAYS_FATAL_IF(threadName == nullptr, "threadName not provided to javaCreateThreadEtc");
 
     args[0] = (void*) entryFunction;
     args[1] = userData;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index fbc96c2..6444c6c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1483,11 +1483,21 @@
 
     <!-- Allows an application to manage access to documents, usually as part
          of a document picker.
+         <p>This permission should <em>only</em> be requested by the platform
+         document management app.  This permission cannot be granted to
+         third-party apps.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.MANAGE_DOCUMENTS"
         android:protectionLevel="signature" />
 
+    <!-- @hide Allows an application to cache content.
+         <p>Not for use by third-party applications.
+         <p>Protection level: signature
+    -->
+    <permission android:name="android.permission.CACHE_CONTENT"
+        android:protectionLevel="signature" />
+
     <!-- ================================== -->
     <!-- Permissions for screenlock         -->
     <!-- ================================== -->
diff --git a/core/res/res/anim/lock_screen_behind_enter.xml b/core/res/res/anim/lock_screen_behind_enter.xml
index 6f3c4d42..c96e280 100644
--- a/core/res/res/anim/lock_screen_behind_enter.xml
+++ b/core/res/res/anim/lock_screen_behind_enter.xml
@@ -16,7 +16,6 @@
   -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000"
         android:detachWallpaper="true"
         android:shareInterpolator="false"
         android:startOffset="100">
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index 3c4ce89..3953264 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -1051,12 +1051,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Əlavə seçimlər üçün toxunun."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB sazlama qoşuludur"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB debaqı deaktivasiya etmək üçün toxunun."</string>
-    <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Baq hesabat verilir..."</string>
+    <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Baq hesabatı verilir..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Baq hesabatı paylaşılsın?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Baq hesabatı paylaşılır..."</string>
-    <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"IT admininiz bu cihazda nasazlıqların aşkarlanması üçün baq hesabatı sorğusu göndərdi. Tətbiqlər və data paylaşıla bilər."</string>
+    <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"İT admininiz bu cihazda nasazlıqların aşkarlanması üçün baq hesabatı sorğusu göndərdi. Tətbiqlər və data paylaşıla bilər."</string>
     <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PAYLAŞIN"</string>
-    <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RƏDD ET"</string>
+    <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RƏDD EDİN"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Klaviaturanı dəyişin"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Klaviaturaları seçin"</string>
     <string name="show_ime" msgid="2506087537466597099">"Fiziki klaviatura aktiv olduğu halda ekranda saxlayın"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index d44c07e..65f5f24 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -909,8 +909,8 @@
     <string name="noApplications" msgid="2991814273936504689">"Ninguna aplicación puede realizar esta acción."</string>
     <string name="aerr_application" msgid="250320989337856518">"La aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> ha dejado de funcionar"</string>
     <string name="aerr_process" msgid="6201597323218674729">"El proceso <xliff:g id="PROCESS">%1$s</xliff:g> ha dejado de funcionar"</string>
-    <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> sigue dejando de funcionar"</string>
-    <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> sigue dejando de funcionar"</string>
+    <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> sigue sin funcionar"</string>
+    <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> sigue sin funcionar"</string>
     <string name="aerr_restart" msgid="9001379185665886595">"Reiniciar aplicación"</string>
     <string name="aerr_reset" msgid="7645427603514220451">"Restablecer y reiniciar aplicación"</string>
     <string name="aerr_report" msgid="5371800241488400617">"Enviar sugerencias"</string>
@@ -1135,7 +1135,7 @@
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fondo de pantalla"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Cambiar fondo de pantalla"</string>
     <string name="notification_listener_binding_label" msgid="2014162835481906429">"Detector de notificaciones"</string>
-    <string name="vr_listener_binding_label" msgid="4316591939343607306">"Procesador de Realidad Virtual"</string>
+    <string name="vr_listener_binding_label" msgid="4316591939343607306">"Procesador de RV"</string>
     <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Proveedor de condiciones"</string>
     <string name="notification_ranker_binding_label" msgid="774540592299064747">"Servicio de clasificación de notificaciones"</string>
     <string name="vpn_title" msgid="19615213552042827">"VPN activada"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 8ac3490..c79befa 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1151,7 +1151,7 @@
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"טפט"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"שנה טפט"</string>
     <string name="notification_listener_binding_label" msgid="2014162835481906429">"מאזין להתראות"</string>
-    <string name="vr_listener_binding_label" msgid="4316591939343607306">"‏מאזין VR"</string>
+    <string name="vr_listener_binding_label" msgid="4316591939343607306">"‏VR ליסנר"</string>
     <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"ספק תנאי"</string>
     <string name="notification_ranker_binding_label" msgid="774540592299064747">"שירות של דירוג הודעות"</string>
     <string name="vpn_title" msgid="19615213552042827">"‏VPN מופעל"</string>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 24b5e07..6d31dd1 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -1135,7 +1135,7 @@
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Артқы фоны"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Артқы фонын өзгерту"</string>
     <string name="notification_listener_binding_label" msgid="2014162835481906429">"Хабар бақылағыш"</string>
-    <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR тыңдаушы"</string>
+    <string name="vr_listener_binding_label" msgid="4316591939343607306">"Виртуалды шынайылық тыңдаушысы"</string>
     <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Шарт провайдері"</string>
     <string name="notification_ranker_binding_label" msgid="774540592299064747">"Хабарландыруларды жіктеу қызметі"</string>
     <string name="vpn_title" msgid="19615213552042827">"VPN белсенді"</string>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index fe89bf9..3a30b55 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -1136,7 +1136,7 @@
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Тушкагаз"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Тушкагазды өзгөртүү"</string>
     <string name="notification_listener_binding_label" msgid="2014162835481906429">"Эскертүү тыңшагычы"</string>
-    <string name="vr_listener_binding_label" msgid="4316591939343607306">"Виртуалдык угуучу"</string>
+    <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR режими"</string>
     <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Шарт түзүүчү"</string>
     <string name="notification_ranker_binding_label" msgid="774540592299064747">"Эскертмени баалоо кызматы"</string>
     <string name="vpn_title" msgid="19615213552042827">"VPN иштетилди"</string>
diff --git a/core/res/res/values-television/config.xml b/core/res/res/values-television/config.xml
index ae19150..3408c21 100644
--- a/core/res/res/values-television/config.xml
+++ b/core/res/res/values-television/config.xml
@@ -25,7 +25,7 @@
     <bool name="config_defaultWindowFeatureOptionsPanel">false</bool>
 
     <!-- Default bounds [left top right bottom] on screen for picture-in-picture windows. -->
-    <string translatable="false" name="config_defaultPictureInPictureBounds">"1420 100 1820 325"</string>
+    <string translatable="false" name="config_defaultPictureInPictureBounds">"1328 54 1808 324"</string>
 
     <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows, when the PIP
          is located in center. -->
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 4ca1825..f95a37d 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -1135,7 +1135,7 @@
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fon rasmi"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Fon rasmini o‘zgartirish"</string>
     <string name="notification_listener_binding_label" msgid="2014162835481906429">"Bildirishnoma tinglovchisi"</string>
-    <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR tinglovchisi"</string>
+    <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR rejimi"</string>
     <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Shartlarni taqdim etuvchi"</string>
     <string name="notification_ranker_binding_label" msgid="774540592299064747">"Bildirishnomalarni baholash xizmati"</string>
     <string name="vpn_title" msgid="19615213552042827">"VPN faollashtirildi"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 51cd029..01b2c47 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1860,6 +1860,10 @@
         <item>-1</item>
     </integer-array>
 
+    <!-- When true, local displays that do not contain any of their own content will automatically
+         mirror the content of the default display. -->
+    <bool name="config_localDisplaysMirrorContent">true</bool>
+
     <!-- When true use the linux /dev/input/event subsystem to detect the switch changes
          on the headphone/microphone jack. When false use the older uevent framework. -->
     <bool name="config_useDevInputEventForAudioJack">false</bool>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 17afd92..5d083d7 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4188,10 +4188,6 @@
     <string name="work_mode_off_message">Allow work profile to function, including apps, background sync, and related features.</string>
     <!-- Title for button to turn on work profile. [CHAR LIMIT=NONE] -->
     <string name="work_mode_turn_on">Turn on</string>
-    <!-- Title for dialog displayed when a packge is suspended by device admin. [CHAR LIMIT=30] -->
-    <string name="suspended_package_title">%1$s disabled</string>
-    <!-- Message for dialog displayed when a packge is suspended by device admin. [CHAR LIMIT=NONE] -->
-    <string name="suspended_package_message">Disabled by %1$s administrator. Contact them to learn more.</string>
 
     <!-- Notification title shown when new SMS/MMS is received while the device is locked [CHAR LIMIT=NONE] -->
     <string name="new_sms_notification_title">You have new messages</string>
@@ -4229,7 +4225,7 @@
     <string name="negative_duration">\u2212<xliff:g id="time" example="1:14">%1$s</xliff:g></string>
 
     <!-- Title of notification shown when device has been forced to safe mode after a security compromise. -->
-    <string name="audit_safemode_notification">Factory reset to use this device normally</string>
+    <string name="audit_safemode_notification">Factory reset to use this device without restrictions</string>
     <!-- Description of notification shown when device has been forced to safe mode after a security compromise. -->
     <string name="audit_safemode_notification_details">Touch to learn more.</string>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1470741..f01cce3 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -306,6 +306,7 @@
   <java-symbol type="bool" name="config_freeformWindowManagement" />
   <java-symbol type="bool" name="config_supportsMultiWindow" />
   <java-symbol type="bool" name="config_guestUserEphemeral" />
+  <java-symbol type="bool" name="config_localDisplaysMirrorContent" />
   <java-symbol type="string" name="config_defaultPictureInPictureBounds" />
   <java-symbol type="string" name="config_centeredPictureInPictureBounds" />
   <java-symbol type="string" name="config_pictureInPictureBoundsInRecents" />
@@ -2507,8 +2508,6 @@
   <java-symbol type="string" name="work_mode_off_title" />
   <java-symbol type="string" name="work_mode_off_message" />
   <java-symbol type="string" name="work_mode_turn_on" />
-  <java-symbol type="string" name="suspended_package_title" />
-  <java-symbol type="string" name="suspended_package_message" />
 
   <!-- New SMS notification while phone is locked. -->
   <java-symbol type="string" name="new_sms_notification_title" />
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index cf7978c..c02a01a 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -102,7 +102,7 @@
     <!-- United Kingdom (Great Britain): 4-6 digits, common codes [5-8]xxxx, plus EU:
          http://www.short-codes.com/media/Co-regulatoryCodeofPracticeforcommonshortcodes170206.pdf,
          visual voicemail code for EE: 887 -->
-    <shortcode country="gb" pattern="\\d{4,6}" premium="[5-8]\\d{4}" free="116\\d{3}|887|83669|34664|40406" />
+    <shortcode country="gb" pattern="\\d{4,6}" premium="[5-8]\\d{4}" free="116\\d{3}|2020|35890|61002|61202|887|83669|34664|40406" />
 
     <!-- Georgia: 4 digits, known premium codes listed -->
     <shortcode country="ge" pattern="\\d{4}" premium="801[234]|888[239]" />
@@ -214,7 +214,7 @@
 
     <!-- USA: 5-6 digits (premium codes from https://www.premiumsmsrefunds.com/ShortCodes.htm),
          visual voicemail code for T-Mobile: 122 -->
-    <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:567|578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" free="122|87902" />
+    <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" standard="44567" free="122|87902" />
 
     <!-- Vietnam -->
     <shortcode country="vn" free="5001" />
diff --git a/core/tests/coretests/src/android/net/NetworkStatsTest.java b/core/tests/coretests/src/android/net/NetworkStatsTest.java
index a723977..9074f8a 100644
--- a/core/tests/coretests/src/android/net/NetworkStatsTest.java
+++ b/core/tests/coretests/src/android/net/NetworkStatsTest.java
@@ -17,8 +17,8 @@
 package android.net;
 
 import static android.net.NetworkStats.ROAMING_ALL;
-import static android.net.NetworkStats.ROAMING_DEFAULT;
-import static android.net.NetworkStats.ROAMING_ROAMING;
+import static android.net.NetworkStats.ROAMING_NO;
+import static android.net.NetworkStats.ROAMING_YES;
 import static android.net.NetworkStats.SET_DEFAULT;
 import static android.net.NetworkStats.SET_FOREGROUND;
 import static android.net.NetworkStats.SET_DBG_VPN_IN;
@@ -46,57 +46,57 @@
 
     public void testFindIndex() throws Exception {
         final NetworkStats stats = new NetworkStats(TEST_START, 4)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1024L, 8L, 0L,
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L, 0L,
                         0L, 10)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 0L, 0L, 1024L,
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 1024L,
                         8L, 11)
-                .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1024L, 8L,
+                .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L,
                         1024L, 8L, 12)
-                .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 1024L, 8L,
+                .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_YES, 1024L, 8L,
                         1024L, 8L, 12);
 
-        assertEquals(3, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING));
-        assertEquals(2, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT));
-        assertEquals(1, stats.findIndex(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT));
-        assertEquals(0, stats.findIndex(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT));
-        assertEquals(-1, stats.findIndex(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT));
+        assertEquals(3, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_YES));
+        assertEquals(2, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO));
+        assertEquals(1, stats.findIndex(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO));
+        assertEquals(0, stats.findIndex(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO));
+        assertEquals(-1, stats.findIndex(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE, ROAMING_NO));
     }
 
     public void testFindIndexHinted() {
         final NetworkStats stats = new NetworkStats(TEST_START, 3)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1024L, 8L, 0L,
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L, 0L,
                         0L, 10)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 0L, 0L, 1024L,
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 1024L,
                         8L, 11)
-                .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1024L, 8L,
+                .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L,
                         1024L, 8L, 12)
-                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT, 1024L, 8L,
+                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 1024L, 8L,
                         0L, 0L, 10)
-                .addValues(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 0L, 0L, 1024L,
+                .addValues(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, ROAMING_NO, 0L, 0L, 1024L,
                         8L, 11)
-                .addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1024L, 8L,
+                .addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L,
                         1024L, 8L, 12)
-                .addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 1024L, 8L,
+                .addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, ROAMING_YES, 1024L, 8L,
                         1024L, 8L, 12);
 
         // verify that we correctly find across regardless of hinting
         for (int hint = 0; hint < stats.size(); hint++) {
             assertEquals(0, stats.findIndexHinted(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE,
-                    ROAMING_DEFAULT, hint));
+                    ROAMING_NO, hint));
             assertEquals(1, stats.findIndexHinted(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE,
-                    ROAMING_DEFAULT, hint));
+                    ROAMING_NO, hint));
             assertEquals(2, stats.findIndexHinted(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE,
-                    ROAMING_DEFAULT, hint));
+                    ROAMING_NO, hint));
             assertEquals(3, stats.findIndexHinted(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE,
-                    ROAMING_DEFAULT, hint));
+                    ROAMING_NO, hint));
             assertEquals(4, stats.findIndexHinted(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D,
-                    ROAMING_DEFAULT, hint));
+                    ROAMING_NO, hint));
             assertEquals(5, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE,
-                    ROAMING_DEFAULT, hint));
+                    ROAMING_NO, hint));
             assertEquals(6, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE,
-                    ROAMING_ROAMING, hint));
+                    ROAMING_YES, hint));
             assertEquals(-1, stats.findIndexHinted(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE,
-                    ROAMING_DEFAULT, hint));
+                    ROAMING_NO, hint));
         }
     }
 
@@ -106,41 +106,41 @@
         assertEquals(0, stats.size());
         assertEquals(3, stats.internalSize());
 
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1L, 1L, 2L,
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1L, 1L, 2L,
                 2L, 3);
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 2L, 2L, 2L,
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 2L, 2L, 2L,
                 2L, 4);
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 3L, 3L, 2L,
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_YES, 3L, 3L, 2L,
                 2L, 5);
 
         assertEquals(3, stats.size());
         assertEquals(3, stats.internalSize());
 
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 4L, 40L, 4L,
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 4L, 40L, 4L,
                 40L, 7);
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 5L, 50L, 4L,
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 5L, 50L, 4L,
                 40L, 8);
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 6L, 60L, 5L,
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 6L, 60L, 5L,
                 50L, 10);
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 7L, 70L, 5L,
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_YES, 7L, 70L, 5L,
                 50L, 11);
 
         assertEquals(7, stats.size());
         assertTrue(stats.internalSize() >= 7);
 
-        assertValues(stats, 0, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1L, 1L,
+        assertValues(stats, 0, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1L, 1L,
                 2L, 2L, 3);
-        assertValues(stats, 1, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 2L, 2L,
+        assertValues(stats, 1, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 2L, 2L,
                 2L, 2L, 4);
-        assertValues(stats, 2, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 3L, 3L,
+        assertValues(stats, 2, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_YES, 3L, 3L,
                 2L, 2L, 5);
-        assertValues(stats, 3, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 4L,
+        assertValues(stats, 3, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 4L,
                 40L, 4L, 40L, 7);
-        assertValues(stats, 4, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 5L,
+        assertValues(stats, 4, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 5L,
                 50L, 4L, 40L, 8);
-        assertValues(stats, 5, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 6L,
+        assertValues(stats, 5, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 6L,
                 60L, 5L, 50L, 10);
-        assertValues(stats, 6, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 7L,
+        assertValues(stats, 6, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_YES, 7L,
                 70L, 5L, 50L, 11);
     }
 
@@ -152,19 +152,19 @@
         stats.combineValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, -128L, -1L,
                 -128L, -1L, -1);
 
-        assertValues(stats, 0, TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 384L, 3L,
+        assertValues(stats, 0, TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, ROAMING_NO, 384L, 3L,
                 128L, 1L, 9);
-        assertValues(stats, 1, TEST_IFACE, 1001, SET_DEFAULT, 0xff, ROAMING_DEFAULT, 128L, 1L, 128L,
+        assertValues(stats, 1, TEST_IFACE, 1001, SET_DEFAULT, 0xff, ROAMING_NO, 128L, 1L, 128L,
                 1L, 2);
 
         // now try combining that should create row
         stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L,
                 128L, 1L, 3);
-        assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 128L, 1L,
+        assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 1L,
                 128L, 1L, 3);
         stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L,
                 128L, 1L, 3);
-        assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 256L, 2L,
+        assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, ROAMING_NO, 256L, 2L,
                 256L, 2L, 6);
     }
 
@@ -180,9 +180,9 @@
         final NetworkStats result = after.subtract(before);
 
         // identical data should result in zero delta
-        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 0L, 0L, 0L,
+        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 0L,
                 0L, 0);
-        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 0L, 0L, 0L,
+        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 0L,
                 0L, 0);
     }
 
@@ -198,9 +198,9 @@
         final NetworkStats result = after.subtract(before);
 
         // expect delta between measurements
-        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1L, 1L, 2L,
+        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1L, 1L, 2L,
                 1L, 4);
-        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 3L, 1L, 4L,
+        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 3L, 1L, 4L,
                 1L, 8);
     }
 
@@ -217,11 +217,11 @@
         final NetworkStats result = after.subtract(before);
 
         // its okay to have new rows
-        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 0L, 0L, 0L,
+        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 0L,
                 0L, 0);
-        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 0L, 0L, 0L,
+        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 0L,
                 0L, 0);
-        assertValues(result, 2, TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1024L, 8L,
+        assertValues(result, 2, TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L,
                 1024L, 8L, 20);
     }
 
@@ -237,7 +237,7 @@
 
         // should silently drop omitted rows
         assertEquals(1, result.size());
-        assertValues(result, 0, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1L,
+        assertValues(result, 0, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1L,
                 2L, 3L, 4L, 0);
         assertEquals(4L, result.getTotalBytes());
     }
@@ -264,11 +264,11 @@
         assertEquals(64L, uidTag.getTotalBytes());
 
         final NetworkStats uidRoaming = new NetworkStats(TEST_START, 3)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 32L, 0L, 0L, 0L,
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L, 0L, 0L,
                         0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 32L, 0L, 0L, 0L,
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L, 0L, 0L,
                         0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 32L, 0L, 0L, 0L,
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_YES, 32L, 0L, 0L, 0L,
                         0L);
         assertEquals(96L, uidRoaming.getTotalBytes());
     }
@@ -283,11 +283,11 @@
 
     public void testGroupedByIfaceAll() throws Exception {
         final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
-                .addValues(IFACE_ALL, 100, SET_ALL, TAG_NONE, ROAMING_DEFAULT, 128L, 8L, 0L, 2L,
+                .addValues(IFACE_ALL, 100, SET_ALL, TAG_NONE, ROAMING_NO, 128L, 8L, 0L, 2L,
                         20L)
-                .addValues(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT, 128L, 8L, 0L,
+                .addValues(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 128L, 8L, 0L,
                         2L, 20L)
-                .addValues(IFACE_ALL, 101, SET_ALL, TAG_NONE, ROAMING_ROAMING, 128L, 8L, 0L, 2L,
+                .addValues(IFACE_ALL, 101, SET_ALL, TAG_NONE, ROAMING_YES, 128L, 8L, 0L, 2L,
                         20L);
         final NetworkStats grouped = uidStats.groupedByIface();
 
@@ -300,19 +300,19 @@
 
     public void testGroupedByIface() throws Exception {
         final NetworkStats uidStats = new NetworkStats(TEST_START, 7)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 128L, 8L, 0L,
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L, 0L,
                         2L, 20L)
-                .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 512L, 32L, 0L,
+                .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 512L, 32L, 0L,
                         0L, 0L)
-                .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 64L, 4L, 0L, 0L,
+                .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 4L, 0L, 0L,
                         0L)
-                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT, 512L, 32L,
+                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 512L, 32L,
                         0L, 0L, 0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 128L, 8L, 0L,
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L, 0L,
                         0L, 0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 128L, 8L, 0L, 0L,
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_NO, 128L, 8L, 0L, 0L,
                         0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 128L, 8L, 0L,
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_YES, 128L, 8L, 0L,
                         0L, 0L);
 
         final NetworkStats grouped = uidStats.groupedByIface();
@@ -328,49 +328,49 @@
 
     public void testAddAllValues() {
         final NetworkStats first = new NetworkStats(TEST_START, 5)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 32L, 0L, 0L, 0L,
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L, 0L, 0L,
                         0L)
-                .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT, 32L, 0L, 0L,
+                .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 32L, 0L, 0L,
                         0L, 0L)
-                .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_ROAMING, 32L, 0L, 0L,
+                .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_YES, 32L, 0L, 0L,
                         0L, 0L);
 
         final NetworkStats second = new NetworkStats(TEST_START, 2)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 32L, 0L, 0L, 0L,
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L, 0L, 0L,
                         0L)
-                .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 32L, 0L,
+                .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L,
                         0L, 0L, 0L)
-                .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_ROAMING, 32L, 0L, 0L,
+                .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_YES, 32L, 0L, 0L,
                         0L, 0L);
 
         first.combineAllValues(second);
 
         assertEquals(4, first.size());
-        assertValues(first, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 64L, 0L, 0L,
+        assertValues(first, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 64L, 0L, 0L,
                 0L, 0L);
-        assertValues(first, 1, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT, 32L, 0L,
+        assertValues(first, 1, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 32L, 0L,
                 0L, 0L, 0L);
-        assertValues(first, 2, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_ROAMING, 64L, 0L,
+        assertValues(first, 2, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_YES, 64L, 0L,
                 0L, 0L, 0L);
-        assertValues(first, 3, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 32L,
+        assertValues(first, 3, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L,
                 0L, 0L, 0L, 0L);
     }
 
     public void testGetTotal() {
         final NetworkStats stats = new NetworkStats(TEST_START, 7)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 128L, 8L, 0L,
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L, 0L,
                         2L, 20L)
-                .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 512L, 32L, 0L,
+                .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 512L, 32L, 0L,
                         0L, 0L)
-                .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 64L, 4L, 0L, 0L,
+                .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 4L, 0L, 0L,
                         0L)
-                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT, 512L, 32L,
+                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 512L, 32L,
                         0L, 0L, 0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 128L, 8L, 0L,
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L, 0L,
                         0L, 0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 128L, 8L, 0L, 0L,
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_NO, 128L, 8L, 0L, 0L,
                         0L)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 128L, 8L, 0L,
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_YES, 128L, 8L, 0L,
                         0L, 0L);
 
         assertValues(stats.getTotal(null), 1408L, 88L, 0L, 2L, 20L);
@@ -396,9 +396,9 @@
         final NetworkStats after = before.withoutUids(new int[] { 100 });
         assertEquals(6, before.size());
         assertEquals(2, after.size());
-        assertValues(after, 0, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 128L, 8L,
+        assertValues(after, 0, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L,
                 0L, 0L, 0L);
-        assertValues(after, 1, TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 128L, 8L, 0L,
+        assertValues(after, 1, TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_NO, 128L, 8L, 0L,
                 0L, 0L);
     }
 
@@ -457,53 +457,53 @@
         assertEquals(21, delta.size());
 
         // tunIface and TEST_IFACE entries are not changed.
-        assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+        assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE, ROAMING_NO,
                 39605L, 46L, 12259L, 55L, 0L);
-        assertValues(delta, 1, tunIface, 10100, SET_FOREGROUND, TAG_NONE,  ROAMING_DEFAULT, 0L, 0L,
+        assertValues(delta, 1, tunIface, 10100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 0L, 0L,
                 0L, 0L, 0L);
-        assertValues(delta, 2, tunIface, 10120, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+        assertValues(delta, 2, tunIface, 10120, SET_DEFAULT, TAG_NONE, ROAMING_NO,
                 72667L, 197L, 43909L, 241L, 0L);
-        assertValues(delta, 3, tunIface, 10120, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT,
+        assertValues(delta, 3, tunIface, 10120, SET_FOREGROUND, TAG_NONE, ROAMING_NO,
                 9297L, 17L, 4128L, 21L, 0L);
-        assertValues(delta, 4, tunIface, tunUid, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+        assertValues(delta, 4, tunIface, tunUid, SET_DEFAULT, TAG_NONE, ROAMING_NO,
                 4983L, 10L, 1801L, 12L, 0L);
-        assertValues(delta, 5, tunIface, tunUid, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT, 0L, 0L,
+        assertValues(delta, 5, tunIface, tunUid, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 0L, 0L,
                 0L, 0L, 0L);
-        assertValues(delta, 6, tunIface, 10120, SET_DEFAULT, testTag1, ROAMING_DEFAULT,
+        assertValues(delta, 6, tunIface, 10120, SET_DEFAULT, testTag1, ROAMING_NO,
                 21691L, 41L, 13820L, 51L, 0L);
-        assertValues(delta, 7, tunIface, 10120, SET_FOREGROUND, testTag1, ROAMING_DEFAULT, 1281L,
+        assertValues(delta, 7, tunIface, 10120, SET_FOREGROUND, testTag1, ROAMING_NO, 1281L,
                 2L, 665L, 2L, 0L);
-        assertValues(delta, 8, TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1685L, 5L,
+        assertValues(delta, 8, TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1685L, 5L,
                 2070L, 6L, 0L);
 
         // Existing underlying Iface entries are updated
-        assertValues(delta, 9, underlyingIface, 10100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+        assertValues(delta, 9, underlyingIface, 10100, SET_DEFAULT, TAG_NONE, ROAMING_NO,
                 44783L, 54L, 13829L, 60L, 0L);
-        assertValues(delta, 10, underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT,
+        assertValues(delta, 10, underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, ROAMING_NO,
                 0L, 0L, 0L, 0L, 0L);
 
         // VPN underlying Iface entries are updated
-        assertValues(delta, 11, underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+        assertValues(delta, 11, underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, ROAMING_NO,
                 28304L, 27L, 1719L, 12L, 0L);
-        assertValues(delta, 12, underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT,
+        assertValues(delta, 12, underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, ROAMING_NO,
                 0L, 0L, 0L, 0L, 0L);
 
         // New entries are added for new application's underlying Iface traffic
-        assertContains(delta, underlyingIface, 10120, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+        assertContains(delta, underlyingIface, 10120, SET_DEFAULT, TAG_NONE, ROAMING_NO,
                 72667L, 197L, 41872L, 219L, 0L);
-        assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT,
+        assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, TAG_NONE, ROAMING_NO,
                 9297L, 17L, 3936, 19L, 0L);
-        assertContains(delta, underlyingIface, 10120, SET_DEFAULT, testTag1, ROAMING_DEFAULT,
+        assertContains(delta, underlyingIface, 10120, SET_DEFAULT, testTag1, ROAMING_NO,
                 21691L, 41L, 13179L, 46L, 0L);
-        assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, testTag1, ROAMING_DEFAULT,
+        assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, testTag1, ROAMING_NO,
                 1281L, 2L, 634L, 1L, 0L);
 
         // New entries are added for debug purpose
-        assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE, ROAMING_DEFAULT,
+        assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE, ROAMING_NO,
                 39605L, 46L, 11690, 49, 0);
-        assertContains(delta, underlyingIface, 10120, SET_DBG_VPN_IN, TAG_NONE, ROAMING_DEFAULT,
+        assertContains(delta, underlyingIface, 10120, SET_DBG_VPN_IN, TAG_NONE, ROAMING_NO,
                 81964, 214, 45808, 238, 0);
-        assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_IN, TAG_NONE, ROAMING_DEFAULT,
+        assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_IN, TAG_NONE, ROAMING_NO,
                 4983, 10, 1717, 10, 0);
         assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_OUT, TAG_NONE, ROAMING_ALL,
                 126552, 270, 59215, 297, 0);
diff --git a/core/tests/coretests/src/android/text/method/BackspaceTest.java b/core/tests/coretests/src/android/text/method/BackspaceTest.java
index d2e811c..3be9cfc 100644
--- a/core/tests/coretests/src/android/text/method/BackspaceTest.java
+++ b/core/tests/coretests/src/android/text/method/BackspaceTest.java
@@ -29,7 +29,8 @@
 /**
  * Test backspace key handling of {@link android.text.method.BaseKeyListner}.
  *
- * TODO: Move some of test cases to the CTS.
+ * Only contains edge cases. For normal cases, see {@see android.text.method.cts.BackspaceTest}.
+ * TODO: introduce test cases for surrogate pairs and replacement span.
  */
 public class BackspaceTest extends KeyListenerTestCase {
     private static final BaseKeyListener mKeyListener = new BaseKeyListener() {
@@ -65,85 +66,9 @@
     }
 
     @SmallTest
-    public void testSurrogatePairs() {
-        EditorState state = new EditorState();
-
-        state.setByString("U+1F441 |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
-        state.setByString("U+1F441 U+1F5E8 |");
-        backspace(state, 0);
-        state.assertEquals("U+1F441 |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
-        // TODO: introduce edge cases.
-    }
-
-    @SmallTest
-    public void testReplacementSpan() {
-        EditorState state = new EditorState();
-
-        // ReplacementSpan will be set to "()" region.
-        state.setByString("'abc' ( 'de' ) 'fg' |");
-        backspace(state, 0);
-        state.assertEquals("'abc' ( 'de' ) 'f' |");
-        backspace(state, 0);
-        state.assertEquals("'abc' ( 'de' ) |");
-        backspace(state, 0);
-        state.assertEquals("'abc' |");
-        backspace(state, 0);
-        state.assertEquals("'ab' |");
-        backspace(state, 0);
-        state.assertEquals("'a' |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
-        state.setByString("'abc' [ ( 'de' ) ] 'fg'");
-        backspace(state, 0);
-        state.assertEquals("'abc' | 'fg'");
-        backspace(state, 0);
-        state.assertEquals("'ab' | 'fg'");
-        backspace(state, 0);
-        state.assertEquals("'a' | 'fg'");
-        backspace(state, 0);
-        state.assertEquals("| 'fg'");
-        backspace(state, 0);
-        state.assertEquals("| 'fg'");
-
-        state.setByString("'ab' [ 'c' ( 'de' ) 'f' ] 'g'");
-        backspace(state, 0);
-        state.assertEquals("'ab' | 'g'");
-        backspace(state, 0);
-        state.assertEquals("'a' | 'g'");
-        backspace(state, 0);
-        state.assertEquals("| 'g'");
-        backspace(state, 0);
-        state.assertEquals("| 'g'");
-
-        // TODO: introduce edge cases.
-    }
-
-    @SmallTest
     public void testCombiningEnclosingKeycaps() {
         EditorState state = new EditorState();
 
-        // U+20E3 is COMBINING ENCLOSING KEYCAP.
-        state.setByString("'1' U+20E3 |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
-        // Variation selector before COMBINING ECLOSING KEYCAP
-        state.setByString("'1' U+FE0E U+20E3 |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
-        state.setByString("'1' U+E0101 U+20E3 |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
-        // Edge cases
         // multiple COMBINING ENCLOSING KEYCAP
         state.setByString("'1' U+20E3 U+20E3 |");
         backspace(state, 0);
@@ -168,17 +93,6 @@
     public void testVariationSelector() {
         EditorState state = new EditorState();
 
-        // U+FE0F is VARIATION SELECTOR-16.
-        state.setByString("'#' U+FE0F |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
-        // U+E0100 is VARIATION SELECTOR-17.
-        state.setByString("U+845B U+E0100 |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
-        // Edge cases
         // Isolated variation selector
         state.setByString("U+FE0F |");
         backspace(state, 0);
@@ -243,20 +157,6 @@
     public void testEmojiZWJSequence() {
         EditorState state = new EditorState();
 
-        // U+200D is ZERO WIDTH JOINER.
-        state.setByString("U+1F441 U+200D U+1F5E8 |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
-        state.setByString("U+1F441 U+200D U+1F5E8 U+FE0E |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
-        state.setByString("U+1F468 U+200D U+2764 U+FE0F U+200D U+1F48B U+200D U+1F468 |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
-        // Edge cases
         // End with ZERO WIDTH JOINER
         state.setByString("U+1F441 U+200D |");
         backspace(state, 0);
@@ -307,35 +207,6 @@
     public void testFlags() {
         EditorState state = new EditorState();
 
-        // U+1F1FA is REGIONAL INDICATOR SYMBOL LETTER U.
-        // U+1F1F8 is REGIONAL INDICATOR SYMBOL LETTER S.
-        state.setByString("U+1F1FA U+1F1F8 |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
-        state.setByString("'a' U+1F1FA U+1F1F8 |");
-        backspace(state, 0);
-        state.assertEquals("'a' |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
-        state.setByString("U+1F1FA U+1F1F8 U+1F1FA U+1F1F8 |");
-        backspace(state, 0);
-        state.assertEquals("U+1F1FA U+1F1F8 |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
-        state.setByString("'a' U+1F1FA U+1F1F8 'b' U+1F1FA U+1F1F8 |");
-        backspace(state, 0);
-        state.assertEquals("'a' U+1F1FA U+1F1F8 'b' |");
-        backspace(state, 0);
-        state.assertEquals("'a' U+1F1FA U+1F1F8 |");
-        backspace(state, 0);
-        state.assertEquals("'a' |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
-        // Edcae cases
         // Isolated regional indicator symbol
         state.setByString("U+1F1FA |");
         backspace(state, 0);
@@ -353,12 +224,6 @@
     public void testEmojiModifier() {
         EditorState state = new EditorState();
 
-        // U+1F3FB is EMOJI MODIFIER FITZPATRICK TYPE-1-2.
-        state.setByString("U+1F466 U+1F3FB |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
-        // Edge cases
         // Isolated emoji modifier
         state.setByString("U+1F3FB |");
         backspace(state, 0);
diff --git a/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
index da17045..f7dab2d 100644
--- a/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
+++ b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
@@ -29,7 +29,8 @@
 /**
  * Test forward delete key handling of  {@link android.text.method.BaseKeyListener}.
  *
- * TODO: Move some of test cases to the CTS.
+ * Only contains edge cases. For normal cases, see {@see android.text.method.cts.ForwardDeleteTest}.
+ * TODO: introduce test cases for surrogate pairs and replacement span.
  */
 public class ForwardDeleteTest extends KeyListenerTestCase {
     private static final BaseKeyListener mKeyListener = new BaseKeyListener() {
@@ -65,73 +66,9 @@
     }
 
     @SmallTest
-    public void testSurrogatePairs() {
-        EditorState state = new EditorState();
-
-        // U+1F441 is EYE
-        state.setByString("| U+1F441");
-        forwardDelete(state, 0);
-        state.assertEquals("|");
-
-        // U+1F5E8 is LEFT SPEECH BUBBLE
-        state.setByString("| U+1F441 U+1F5E8");
-        forwardDelete(state, 0);
-        state.assertEquals("| U+1F5E8");
-        forwardDelete(state, 0);
-        state.assertEquals("|");
-
-        // TODO: introduce edge cases.
-    }
-
-    @SmallTest
-    public void testReplacementSpan() {
-        EditorState state = new EditorState();
-
-        state.setByString("| 'abc' ( 'de' ) 'fg'");
-        forwardDelete(state, 0);
-        state.assertEquals("| 'bc' ( 'de' ) 'fg'");
-        forwardDelete(state, 0);
-        state.assertEquals("| 'c' ( 'de' ) 'fg'");
-        forwardDelete(state, 0);
-        state.assertEquals("| ( 'de' ) 'fg'");
-        forwardDelete(state, 0);
-        state.assertEquals("| 'fg'");
-        forwardDelete(state, 0);
-        state.assertEquals("| 'g'");
-        forwardDelete(state, 0);
-        state.assertEquals("|");
-
-        state.setByString("'abc' [ ( 'de' ) ] 'fg'");
-        forwardDelete(state, 0);
-        state.assertEquals("'abc' | 'fg'");
-        forwardDelete(state, 0);
-        state.assertEquals("'abc' | 'g'");
-        forwardDelete(state, 0);
-        state.assertEquals("'abc' |");
-        forwardDelete(state, 0);
-        state.assertEquals("'abc' |");
-
-        state.setByString("'ab' [ 'c' ( 'de' ) 'f' ] 'g'");
-        forwardDelete(state, 0);
-        state.assertEquals("'ab' | 'g'");
-        forwardDelete(state, 0);
-        state.assertEquals("'ab' |");
-        forwardDelete(state, 0);
-        state.assertEquals("'ab' |");
-
-        // TODO: introduce edge cases.
-    }
-
-    @SmallTest
     public void testCombiningEnclosingKeycaps() {
         EditorState state = new EditorState();
 
-        // U+20E3 is COMBINING ENCLOSING KEYCAP.
-        state.setByString("| '1' U+20E3");
-        forwardDelete(state, 0);
-        state.assertEquals("|");
-
-        // Edge cases
         // multiple COMBINING ENCLOSING KEYCAP
         state.setByString("| '1' U+20E3 U+20E3");
         forwardDelete(state, 0);
@@ -152,17 +89,6 @@
     public void testVariationSelector() {
         EditorState state = new EditorState();
 
-        // U+FE0F is VARIATION SELECTOR-16.
-        state.setByString("| '#' U+FE0F");
-        forwardDelete(state, 0);
-        state.assertEquals("|");
-
-        // U+E0100 is VARIATION SELECTOR-17.
-        state.setByString("| U+845B U+E0100");
-        forwardDelete(state, 0);
-        state.assertEquals("|");
-
-        // Edge cases
         // Isolated variation selectors
         state.setByString("| U+FE0F");
         forwardDelete(state, 0);
@@ -211,16 +137,6 @@
     public void testEmojiZeroWidthJoinerSequence() {
         EditorState state = new EditorState();
 
-        // U+200D is ZERO WIDTH JOINER.
-        state.setByString("| U+1F441 U+200D U+1F5E8");
-        forwardDelete(state, 0);
-        state.assertEquals("|");
-
-        state.setByString("| U+1F468 U+200D U+2764 U+FE0F U+200D U+1F48B U+200D U+1F468");
-        forwardDelete(state, 0);
-        state.assertEquals("|");
-
-        // Edge cases
         // End with ZERO WIDTH JOINER
         state.setByString("| U+1F441 U+200D");
         forwardDelete(state, 0);
@@ -255,19 +171,6 @@
     public void testFlags() {
         EditorState state = new EditorState();
 
-        // U+1F1FA is REGIONAL INDICATOR SYMBOL LETTER U.
-        // U+1F1F8 is REGIONAL INDICATOR SYMBOL LETTER S.
-        state.setByString("| U+1F1FA U+1F1F8");
-        forwardDelete(state, 0);
-        state.assertEquals("|");
-
-        state.setByString("| U+1F1FA U+1F1F8 U+1F1FA U+1F1F8");
-        forwardDelete(state, 0);
-        state.assertEquals("| U+1F1FA U+1F1F8");
-        forwardDelete(state, 0);
-        state.assertEquals("|");
-
-        // Edge cases
         // Isolated regional indicator symbol
         state.setByString("| U+1F1FA");
         forwardDelete(state, 0);
@@ -285,12 +188,6 @@
     public void testEmojiModifier() {
         EditorState state = new EditorState();
 
-        // U+1F3FB is EMOJI MODIFIER FITZPATRICK TYPE-1-2.
-        state.setByString("| U+1F466 U+1F3FB");
-        forwardDelete(state, 0);
-        state.assertEquals("|");
-
-        // Edge cases
         // Isolated emoji modifier
         state.setByString("| U+1F3FB");
         forwardDelete(state, 0);
diff --git a/core/tests/coretests/src/android/transition/AutoTransitionTest.java b/core/tests/coretests/src/android/transition/AutoTransitionTest.java
new file mode 100644
index 0000000..834fb7a
--- /dev/null
+++ b/core/tests/coretests/src/android/transition/AutoTransitionTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 The Android Open Source 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.transition;
+
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(AndroidJUnit4.class)
+public class AutoTransitionTest {
+    @Test
+    @SmallTest
+    public void testFadeOutMoveFadeIn() throws Throwable {
+        AutoTransition autoTransition = new AutoTransition();
+        assertEquals(3, autoTransition.getTransitionCount());
+        Transition fadeOut = autoTransition.getTransitionAt(0);
+        assertNotNull(fadeOut);
+        assertTrue(fadeOut instanceof Fade);
+        assertEquals(Visibility.MODE_OUT, ((Fade)fadeOut).getMode());
+
+        Transition move = autoTransition.getTransitionAt(1);
+        assertNotNull(move);
+        assertTrue(move instanceof ChangeBounds);
+
+        Transition fadeIn = autoTransition.getTransitionAt(2);
+        assertNotNull(fadeIn);
+        assertTrue(fadeIn instanceof Fade);
+        assertEquals(Visibility.MODE_IN, ((Fade)fadeIn).getMode());
+
+        assertEquals(TransitionSet.ORDERING_SEQUENTIAL, autoTransition.getOrdering());
+    }
+}
diff --git a/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java b/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java
index 3d8fe69..a37abf1 100644
--- a/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java
+++ b/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java
@@ -32,6 +32,8 @@
 
 /**
  * SuggestionsPopupWindowTest tests.
+ *
+ * TODO: Add tests for when there are no suggestions
  */
 public class SuggestionsPopupWindowTest extends ActivityInstrumentationTestCase2<TextViewActivity> {
 
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
index 844eadb..4a4727f 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
@@ -47,6 +47,8 @@
 import android.support.test.espresso.action.EspressoKey;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.text.Selection;
+import android.text.Spannable;
 import android.view.KeyEvent;
 
 import static org.hamcrest.Matchers.anyOf;
@@ -534,4 +536,68 @@
                 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('i')));
         onView(withId(R.id.textview)).check(hasSelection("hijk"));
     }
+
+    @SmallTest
+    public void testSetSelectionAndActionMode() throws Exception {
+        final String text = "abc def";
+        onView(withId(R.id.textview)).perform(click());
+        onView(withId(R.id.textview)).perform(replaceText(text));
+
+        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+        assertFloatingToolbarIsNotDisplayed();
+        textView.post(() -> Selection.setSelection((Spannable) textView.getText(), 0, 3));
+        getInstrumentation().waitForIdleSync();
+        sleepForFloatingToolbarPopup();
+        // Don't automatically start action mode.
+        assertFloatingToolbarIsNotDisplayed();
+        // Make sure that "Select All" is included in the selection action mode when the entire text
+        // is not selected.
+        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('e')));
+        sleepForFloatingToolbarPopup();
+        assertFloatingToolbarIsDisplayed();
+        // Changing the selection range by API should not interrupt the selection action mode.
+        textView.post(() -> Selection.setSelection((Spannable) textView.getText(), 0, 3));
+        getInstrumentation().waitForIdleSync();
+        sleepForFloatingToolbarPopup();
+        assertFloatingToolbarIsDisplayed();
+        assertFloatingToolbarContainsItem(
+                getActivity().getString(com.android.internal.R.string.selectAll));
+        // Make sure that "Select All" is no longer included when the entire text is selected by
+        // API.
+        textView.post(
+                () -> Selection.setSelection((Spannable) textView.getText(), 0, text.length()));
+        getInstrumentation().waitForIdleSync();
+        sleepForFloatingToolbarPopup();
+        assertFloatingToolbarIsDisplayed();
+        assertFloatingToolbarDoesNotContainItem(
+                getActivity().getString(com.android.internal.R.string.selectAll));
+        // Make sure that shrinking the selection range to cursor (an empty range) by API
+        // terminates selection action mode and does not trigger the insertion action mode.
+        textView.post(() -> Selection.setSelection((Spannable) textView.getText(), 0));
+        getInstrumentation().waitForIdleSync();
+        sleepForFloatingToolbarPopup();
+        assertFloatingToolbarIsNotDisplayed();
+        // Make sure that user click can trigger the insertion action mode.
+        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
+        onHandleView(com.android.internal.R.id.insertion_handle).perform(click());
+        sleepForFloatingToolbarPopup();
+        assertFloatingToolbarIsDisplayed();
+        // Make sure that an existing insertion action mode keeps alive after the insertion point is
+        // moved by API.
+        textView.post(() -> Selection.setSelection((Spannable) textView.getText(), 0));
+        getInstrumentation().waitForIdleSync();
+        sleepForFloatingToolbarPopup();
+        assertFloatingToolbarIsDisplayed();
+        assertFloatingToolbarDoesNotContainItem(
+                getActivity().getString(com.android.internal.R.string.copy));
+        // Make sure that selection action mode is started after selection is created by API when
+        // insertion action mode is active.
+        textView.post(
+                () -> Selection.setSelection((Spannable) textView.getText(), 1, text.length()));
+        getInstrumentation().waitForIdleSync();
+        sleepForFloatingToolbarPopup();
+        assertFloatingToolbarIsDisplayed();
+        assertFloatingToolbarContainsItem(
+                getActivity().getString(com.android.internal.R.string.copy));
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
index 12a75b8..327f3fd 100644
--- a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
+++ b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.net;
 
-import static android.net.NetworkStats.ROAMING_DEFAULT;
+import static android.net.NetworkStats.ROAMING_NO;
 import static android.net.NetworkStats.SET_ALL;
 import static android.net.NetworkStats.SET_DEFAULT;
 import static android.net.NetworkStats.SET_FOREGROUND;
@@ -157,7 +157,7 @@
 
     private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
             int tag, long rxBytes, long txBytes) {
-        final int i = stats.findIndex(iface, uid, set, tag, ROAMING_DEFAULT);
+        final int i = stats.findIndex(iface, uid, set, tag, ROAMING_NO);
         final NetworkStats.Entry entry = stats.getValues(i, null);
         assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
         assertEquals("unexpected txBytes", txBytes, entry.txBytes);
@@ -165,7 +165,7 @@
 
     private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
             int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) {
-        final int i = stats.findIndex(iface, uid, set, tag, ROAMING_DEFAULT);
+        final int i = stats.findIndex(iface, uid, set, tag, ROAMING_NO);
         final NetworkStats.Entry entry = stats.getValues(i, null);
         assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
         assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java
index d312454..3e86e6f 100644
--- a/graphics/java/android/graphics/Outline.java
+++ b/graphics/java/android/graphics/Outline.java
@@ -32,7 +32,7 @@
  * @see Drawable#getOutline(Outline)
  */
 public final class Outline {
-    private static final float RADIUS_UNDEFINED = -1.0f;
+    private static final float RADIUS_UNDEFINED = Float.NEGATIVE_INFINITY;
 
     /** @hide */
     public Path mPath;
@@ -196,11 +196,11 @@
     }
 
     /**
-     * Returns the rounded rect radius, if set, or {@code -1} if a path has
+     * Returns the rounded rect radius, if set, or a value less than 0 if a path has
      * been set via {@link #setConvexPath(Path)}. A return value of {@code 0}
      * indicates a non-rounded rect.
      *
-     * @return the rounded rect radius or {@code -1}
+     * @return the rounded rect radius, or value < 0
      */
     public float getRadius() {
         return mRadius;
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 39ea205..ae9ebc7 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -27,6 +27,7 @@
 import android.annotation.Nullable;
 import android.app.ActivityThread;
 import android.app.Application;
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
@@ -156,7 +157,7 @@
     private static final boolean DBG_ANIMATION_VECTOR_DRAWABLE = false;
 
     /** Local, mutable animator set. */
-    private VectorDrawableAnimator mAnimatorSet = new VectorDrawableAnimatorRT(this);
+    private VectorDrawableAnimator mAnimatorSet = new VectorDrawableAnimatorUI(this);
 
     /**
      * The resources against which this drawable was created. Used to attempt
@@ -230,7 +231,7 @@
     }
 
     @Override
-    public int getChangingConfigurations() {
+    public @Config int getChangingConfigurations() {
         return super.getChangingConfigurations() | mAnimatedVectorState.getChangingConfigurations();
     }
 
@@ -449,7 +450,7 @@
     }
 
     private static class AnimatedVectorDrawableState extends ConstantState {
-        int mChangingConfigurations;
+        @Config int mChangingConfigurations;
         VectorDrawable mVectorDrawable;
 
         /** Animators that require a theme before inflation. */
@@ -513,7 +514,7 @@
         }
 
         @Override
-        public int getChangingConfigurations() {
+        public @Config int getChangingConfigurations() {
             return mChangingConfigurations;
         }
 
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index bffbc75..9d8ede0 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -17,6 +17,7 @@
 package android.graphics.drawable;
 
 import android.annotation.NonNull;
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
@@ -454,7 +455,7 @@
     }
 
     @Override
-    public int getChangingConfigurations() {
+    public @Config int getChangingConfigurations() {
         return super.getChangingConfigurations() | mBitmapState.getChangingConfigurations();
     }
 
@@ -910,7 +911,7 @@
         int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
         boolean mAutoMirrored = false;
 
-        int mChangingConfigurations;
+        @Config int mChangingConfigurations;
         boolean mRebuildShader;
 
         BitmapState(Bitmap bitmap) {
@@ -958,7 +959,7 @@
         }
 
         @Override
-        public int getChangingConfigurations() {
+        public @Config int getChangingConfigurations() {
             return mChangingConfigurations
                     | (mTint != null ? mTint.getChangingConfigurations() : 0);
         }
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index 5ad31f7..7524cac 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -18,6 +18,7 @@
 
 import android.annotation.ColorInt;
 import android.annotation.NonNull;
+import android.content.pm.ActivityInfo.Config;
 import android.graphics.*;
 import android.graphics.PorterDuff.Mode;
 import android.content.res.ColorStateList;
@@ -70,7 +71,7 @@
     }
 
     @Override
-    public int getChangingConfigurations() {
+    public @Config int getChangingConfigurations() {
         return super.getChangingConfigurations() | mColorState.getChangingConfigurations();
     }
 
@@ -292,7 +293,7 @@
         int mBaseColor; // base color, independent of setAlpha()
         @ViewDebug.ExportedProperty
         int mUseColor;  // basecolor modulated by setAlpha()
-        int mChangingConfigurations;
+        @Config int mChangingConfigurations;
         ColorStateList mTint = null;
         Mode mTintMode = DEFAULT_TINT_MODE;
 
@@ -326,7 +327,7 @@
         }
 
         @Override
-        public int getChangingConfigurations() {
+        public @Config int getChangingConfigurations() {
             return mChangingConfigurations
                     | (mTint != null ? mTint.getChangingConfigurations() : 0);
         }
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index f106c68..3915984 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -19,6 +19,7 @@
 import android.annotation.ColorInt;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
@@ -134,7 +135,7 @@
 
     private int[] mStateSet = StateSet.WILD_CARD;
     private int mLevel = 0;
-    private int mChangingConfigurations = 0;
+    private @Config int mChangingConfigurations = 0;
     private Rect mBounds = ZERO_BOUNDS_RECT;  // lazily becomes a new Rect()
     private WeakReference<Callback> mCallback = null;
     private boolean mVisible = true;
@@ -249,7 +250,7 @@
      *
      * @see android.content.pm.ActivityInfo
      */
-    public void setChangingConfigurations(int configs) {
+    public void setChangingConfigurations(@Config int configs) {
         mChangingConfigurations = configs;
     }
 
@@ -266,7 +267,7 @@
      *
      * @see android.content.pm.ActivityInfo
      */
-    public int getChangingConfigurations() {
+    public @Config int getChangingConfigurations() {
         return mChangingConfigurations;
     }
 
@@ -1294,7 +1295,7 @@
          * Return a bit mask of configuration changes that will impact
          * this drawable (and thus require completely reloading it).
          */
-        public abstract int getChangingConfigurations();
+        public abstract @Config int getChangingConfigurations();
 
         /**
          * @return Total pixel count
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index a91d1f0..42f4863 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -17,6 +17,7 @@
 package android.graphics.drawable;
 
 import android.annotation.NonNull;
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
@@ -87,7 +88,7 @@
     }
 
     @Override
-    public int getChangingConfigurations() {
+    public @Config int getChangingConfigurations() {
         return super.getChangingConfigurations()
                 | mDrawableContainerState.getChangingConfigurations();
     }
@@ -649,8 +650,8 @@
 
         Resources mSourceRes;
         int mDensity = DisplayMetrics.DENSITY_DEFAULT;
-        int mChangingConfigurations;
-        int mChildrenChangingConfigurations;
+        @Config int mChangingConfigurations;
+        @Config int mChildrenChangingConfigurations;
 
         SparseArray<ConstantState> mDrawableFutures;
         Drawable[] mDrawables;
@@ -781,7 +782,7 @@
         }
 
         @Override
-        public int getChangingConfigurations() {
+        public @Config int getChangingConfigurations() {
             return mChangingConfigurations | mChildrenChangingConfigurations;
         }
 
diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java
index 4df2d57..5abfc54 100644
--- a/graphics/java/android/graphics/drawable/DrawableWrapper.java
+++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java
@@ -23,6 +23,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
@@ -229,7 +230,7 @@
     }
 
     @Override
-    public int getChangingConfigurations() {
+    public @Config int getChangingConfigurations() {
         return super.getChangingConfigurations()
                 | (mState != null ? mState.getChangingConfigurations() : 0)
                 | mDrawable.getChangingConfigurations();
@@ -444,7 +445,7 @@
     abstract static class DrawableWrapperState extends Drawable.ConstantState {
         private int[] mThemeAttrs;
 
-        int mChangingConfigurations;
+        @Config int mChangingConfigurations;
         int mDensity = DisplayMetrics.DENSITY_DEFAULT;
 
         Drawable.ConstantState mDrawableState;
@@ -524,7 +525,7 @@
         public abstract Drawable newDrawable(@Nullable Resources res);
 
         @Override
-        public int getChangingConfigurations() {
+        public @Config int getChangingConfigurations() {
             return mChangingConfigurations
                     | (mDrawableState != null ? mDrawableState.getChangingConfigurations() : 0);
         }
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 7b1e62a..bcc354c 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -20,6 +20,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
@@ -958,7 +959,7 @@
     }
 
     @Override
-    public int getChangingConfigurations() {
+    public @Config int getChangingConfigurations() {
         return super.getChangingConfigurations() | mGradientState.getChangingConfigurations();
     }
 
@@ -1734,7 +1735,7 @@
     }
 
     final static class GradientState extends ConstantState {
-        public int mChangingConfigurations;
+        public @Config int mChangingConfigurations;
         public @Shape int mShape = RECTANGLE;
         public @GradientType int mGradient = LINEAR_GRADIENT;
         public int mAngle = 0;
@@ -1962,7 +1963,7 @@
         }
 
         @Override
-        public int getChangingConfigurations() {
+        public @Config int getChangingConfigurations() {
             return mChangingConfigurations
                     | (mStrokeColors != null ? mStrokeColors.getChangingConfigurations() : 0)
                     | (mSolidColors != null ? mSolidColors.getChangingConfigurations() : 0)
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index d142f95..d9c3a02 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
@@ -88,7 +89,7 @@
      * @see #getLayerInsetStart(int)
      * @see #getLayerInsetEnd(int)
      */
-    public static final int UNDEFINED_INSET = Integer.MIN_VALUE;
+    public static final int INSET_UNDEFINED = Integer.MIN_VALUE;
 
     LayerState mLayerState;
 
@@ -758,7 +759,7 @@
      * @attr ref android.R.styleable#LayerDrawableItem_bottom
      */
     public void setLayerInset(int index, int l, int t, int r, int b) {
-        setLayerInsetInternal(index, l, t, r, b, UNDEFINED_INSET, UNDEFINED_INSET);
+        setLayerInsetInternal(index, l, t, r, b, INSET_UNDEFINED, INSET_UNDEFINED);
     }
 
     /**
@@ -873,7 +874,7 @@
     /**
      * @param index the index of the layer
      * @return the number of pixels to inset from the start bound, or
-     *         {@link #UNDEFINED_INSET} if not specified
+     *         {@link #INSET_UNDEFINED} if not specified
      * @attr ref android.R.styleable#LayerDrawableItem_start
      */
     public int getLayerInsetStart(int index) {
@@ -884,7 +885,7 @@
     /**
      * @param index the index of the layer to adjust
      * @param e number of pixels to inset from the end bound, or
-     *         {@link #UNDEFINED_INSET} if not specified
+     *         {@link #INSET_UNDEFINED} if not specified
      * @attr ref android.R.styleable#LayerDrawableItem_end
      */
     public void setLayerInsetEnd(int index, int e) {
@@ -971,7 +972,7 @@
     }
 
     @Override
-    public int getChangingConfigurations() {
+    public @Config int getChangingConfigurations() {
         return super.getChangingConfigurations() | mLayerState.getChangingConfigurations();
     }
 
@@ -1502,8 +1503,8 @@
             // insets.
             final int insetRtlL = isLayoutRtl ? r.mInsetE : r.mInsetS;
             final int insetRtlR = isLayoutRtl ? r.mInsetS : r.mInsetE;
-            final int insetL = insetRtlL == UNDEFINED_INSET ? r.mInsetL : insetRtlL;
-            final int insetR = insetRtlR == UNDEFINED_INSET ? r.mInsetR : insetRtlR;
+            final int insetL = insetRtlL == INSET_UNDEFINED ? r.mInsetL : insetRtlL;
+            final int insetR = insetRtlR == INSET_UNDEFINED ? r.mInsetR : insetRtlR;
 
             // Establish containing region based on aggregate padding and
             // requested insets for the current layer.
@@ -1601,8 +1602,8 @@
             // left / right ones.
             final int insetRtlL = isLayoutRtl ? r.mInsetE : r.mInsetS;
             final int insetRtlR = isLayoutRtl ? r.mInsetS : r.mInsetE;
-            final int insetL = insetRtlL == UNDEFINED_INSET ? r.mInsetL : insetRtlL;
-            final int insetR = insetRtlR == UNDEFINED_INSET ? r.mInsetR : insetRtlR;
+            final int insetL = insetRtlL == INSET_UNDEFINED ? r.mInsetL : insetRtlL;
+            final int insetR = insetRtlR == INSET_UNDEFINED ? r.mInsetR : insetRtlR;
 
             // Don't apply padding and insets for children that don't have
             // an intrinsic dimension.
@@ -1762,8 +1763,8 @@
         public int[] mThemeAttrs;
         public int mDensity = DisplayMetrics.DENSITY_DEFAULT;
         public int mInsetL, mInsetT, mInsetR, mInsetB;
-        public int mInsetS = UNDEFINED_INSET;
-        public int mInsetE = UNDEFINED_INSET;
+        public int mInsetS = INSET_UNDEFINED;
+        public int mInsetE = INSET_UNDEFINED;
         public int mWidth = -1;
         public int mHeight = -1;
         public int mGravity = Gravity.NO_GRAVITY;
@@ -1832,10 +1833,10 @@
             mInsetT = Drawable.scaleFromDensity(mInsetT, sourceDensity, targetDensity, false);
             mInsetR = Drawable.scaleFromDensity(mInsetR, sourceDensity, targetDensity, false);
             mInsetB = Drawable.scaleFromDensity(mInsetB, sourceDensity, targetDensity, false);
-            if (mInsetS != UNDEFINED_INSET) {
+            if (mInsetS != INSET_UNDEFINED) {
                 mInsetS = Drawable.scaleFromDensity(mInsetS, sourceDensity, targetDensity, false);
             }
-            if (mInsetE != UNDEFINED_INSET) {
+            if (mInsetE != INSET_UNDEFINED) {
                 mInsetE = Drawable.scaleFromDensity(mInsetE, sourceDensity, targetDensity, false);
             }
             if (mWidth > 0) {
@@ -1864,8 +1865,8 @@
         int mPaddingEnd = -1;
         int mOpacityOverride = PixelFormat.UNKNOWN;
 
-        int mChangingConfigurations;
-        int mChildrenChangingConfigurations;
+        @Config int mChangingConfigurations;
+        @Config int mChildrenChangingConfigurations;
 
         private boolean mHaveOpacity;
         private int mOpacity;
@@ -1989,7 +1990,7 @@
         }
 
         @Override
-        public int getChangingConfigurations() {
+        public @Config int getChangingConfigurations() {
             return mChangingConfigurations
                     | mChildrenChangingConfigurations;
         }
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 6816539..fd3b9b4 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
@@ -260,7 +261,7 @@
     }
 
     @Override
-    public int getChangingConfigurations() {
+    public @Config int getChangingConfigurations() {
         return super.getChangingConfigurations() | mNinePatchState.getChangingConfigurations();
     }
 
@@ -575,7 +576,7 @@
     }
 
     final static class NinePatchState extends ConstantState {
-        int mChangingConfigurations;
+        @Config int mChangingConfigurations;
 
         // Values loaded during inflation.
         NinePatch mNinePatch = null;
@@ -651,7 +652,7 @@
         }
 
         @Override
-        public int getChangingConfigurations() {
+        public @Config int getChangingConfigurations() {
             return mChangingConfigurations
                     | (mTint != null ? mTint.getChangingConfigurations() : 0);
         }
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index ee0861a..caf2e7a 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -23,6 +23,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
@@ -1033,7 +1034,7 @@
         }
 
         @Override
-        public int getChangingConfigurations() {
+        public @Config int getChangingConfigurations() {
             return super.getChangingConfigurations()
                     | (mColor != null ? mColor.getChangingConfigurations() : 0);
         }
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 30b588e..fe82a93 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -16,6 +16,7 @@
 
 package android.graphics.drawable;
 
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -260,7 +261,7 @@
     }
 
     @Override
-    public int getChangingConfigurations() {
+    public @Config int getChangingConfigurations() {
         return super.getChangingConfigurations() | mShapeState.getChangingConfigurations();
     }
 
@@ -526,7 +527,7 @@
      */
     final static class ShapeState extends ConstantState {
         int[] mThemeAttrs;
-        int mChangingConfigurations;
+        @Config int mChangingConfigurations;
         Paint mPaint;
         Shape mShape;
         ColorStateList mTint = null;
@@ -571,7 +572,7 @@
         }
 
         @Override
-        public int getChangingConfigurations() {
+        public @Config int getChangingConfigurations() {
             return mChangingConfigurations
                     | (mTint != null ? mTint.getChangingConfigurations() : 0);
         }
diff --git a/graphics/java/android/graphics/drawable/TransitionDrawable.java b/graphics/java/android/graphics/drawable/TransitionDrawable.java
index e5c235e..0122338 100644
--- a/graphics/java/android/graphics/drawable/TransitionDrawable.java
+++ b/graphics/java/android/graphics/drawable/TransitionDrawable.java
@@ -16,6 +16,7 @@
 
 package android.graphics.drawable;
 
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.os.SystemClock;
@@ -259,7 +260,7 @@
         }
 
         @Override
-        public int getChangingConfigurations() {
+        public @Config int getChangingConfigurations() {
             return mChangingConfigurations;
         }
     }
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 44a91fe..ae98c22 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -16,6 +16,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.ActivityInfo.Config;
 import android.content.res.ColorStateList;
 import android.content.res.ComplexColor;
 import android.content.res.GradientColor;
@@ -686,7 +687,7 @@
     }
 
     @Override
-    public int getChangingConfigurations() {
+    public @Config int getChangingConfigurations() {
         return super.getChangingConfigurations() | mVectorState.getChangingConfigurations();
     }
 
@@ -714,7 +715,7 @@
     static class VectorDrawableState extends ConstantState {
         // Variables below need to be copied (deep copy if applicable) for mutation.
         int[] mThemeAttrs;
-        int mChangingConfigurations;
+        @Config int mChangingConfigurations;
         ColorStateList mTint = null;
         Mode mTintMode = DEFAULT_TINT_MODE;
         boolean mAutoMirrored;
@@ -823,7 +824,7 @@
         }
 
         @Override
-        public int getChangingConfigurations() {
+        public @Config int getChangingConfigurations() {
             return mChangingConfigurations
                     | (mTint != null ? mTint.getChangingConfigurations() : 0);
         }
@@ -923,7 +924,7 @@
 
         // mLocalMatrix is updated based on the update of transformation information,
         // either parsed from the XML or by animation.
-        private int mChangingConfigurations;
+        private @Config int mChangingConfigurations;
         private int[] mThemeAttrs;
         private String mGroupName = null;
 
@@ -1169,7 +1170,7 @@
         protected PathParser.PathData mPathData = null;
 
         String mPathName;
-        int mChangingConfigurations;
+        @Config int mChangingConfigurations;
 
         public VPath() {
             // Empty constructor.
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index f6e3b50..ca07738 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -255,6 +255,7 @@
 ifeq (true, $(HWUI_NEW_OPS))
     LOCAL_SRC_FILES += \
         tests/unit/BakedOpDispatcherTests.cpp \
+        tests/unit/BakedOpRendererTests.cpp \
         tests/unit/BakedOpStateTests.cpp \
         tests/unit/FrameBuilderTests.cpp \
         tests/unit/LeakCheckTests.cpp \
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp
index da5ecca..bb3ea3f 100644
--- a/libs/hwui/BakedOpRenderer.cpp
+++ b/libs/hwui/BakedOpRenderer.cpp
@@ -40,6 +40,16 @@
 void BakedOpRenderer::startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) {
     LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer...");
 
+    // subtract repaintRect from region, since it will be regenerated
+    if (repaintRect.contains(0, 0,
+                offscreenBuffer->viewportWidth, offscreenBuffer->viewportHeight)) {
+        // repaint full layer, so throw away entire region
+        offscreenBuffer->region.clear();
+    } else {
+        offscreenBuffer->region.subtractSelf(android::Rect(repaintRect.left, repaintRect.top,
+                repaintRect.right, repaintRect.bottom));
+    }
+
     mRenderTarget.offscreenBuffer = offscreenBuffer;
 
     // create and bind framebuffer
diff --git a/libs/hwui/ClipArea.cpp b/libs/hwui/ClipArea.cpp
index afe9807..f886dda 100644
--- a/libs/hwui/ClipArea.cpp
+++ b/libs/hwui/ClipArea.cpp
@@ -41,6 +41,10 @@
     return transformedBounds;
 }
 
+void ClipBase::dump() const {
+    ALOGD("mode %d" RECT_STRING, mode, RECT_ARGS(rect));
+}
+
 /*
  * TransformedRectangle
  */
diff --git a/libs/hwui/ClipArea.h b/libs/hwui/ClipArea.h
index 479796d..1654eb8 100644
--- a/libs/hwui/ClipArea.h
+++ b/libs/hwui/ClipArea.h
@@ -106,6 +106,8 @@
     // Bounds of the clipping area, used to define the scissor, and define which
     // portion of the stencil is updated/used
     Rect rect;
+
+    void dump() const;
 };
 
 struct ClipRect : ClipBase {
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index 45fc16c..2799def 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -676,8 +676,11 @@
             fill.skiaShaderData.skiaShaderType);
 
     ALOGD("Glop transform");
-    glop.transform.modelView.dump("model view");
-    glop.transform.canvas.dump("canvas");
+    glop.transform.modelView.dump("  model view");
+    glop.transform.canvas.dump("  canvas");
+    ALOGD_IF(glop.transform.transformFlags, "  transformFlags 0x%x", glop.transform.transformFlags);
+
+    ALOGD_IF(glop.roundRectClipState, "Glop RRCS %p", glop.roundRectClipState);
 
     ALOGD("Glop blend %d %d", glop.blend.src, glop.blend.dst);
     ALOGD("Glop bounds " RECT_STRING, RECT_ARGS(glop.bounds));
diff --git a/libs/hwui/LayerBuilder.cpp b/libs/hwui/LayerBuilder.cpp
index c5af279..e6a95ff 100644
--- a/libs/hwui/LayerBuilder.cpp
+++ b/libs/hwui/LayerBuilder.cpp
@@ -349,8 +349,9 @@
 }
 
 void LayerBuilder::dump() const {
-    ALOGD("LayerBuilder %p, %ux%u buffer %p, blo %p, rn %p",
-            this, width, height, offscreenBuffer, beginLayerOp, renderNode);
+    ALOGD("LayerBuilder %p, %ux%u buffer %p, blo %p, rn %p (%s)",
+            this, width, height, offscreenBuffer, beginLayerOp,
+            renderNode, renderNode ? renderNode->getName() : "-");
     for (const BatchBase* batch : mBatches) {
         batch->dump();
     }
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index f0c79d7..11eb825 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -356,11 +356,15 @@
 }
 void RecordingCanvas::drawRoundRect(float left, float top, float right, float bottom,
             float rx, float ry, const SkPaint& paint) {
-    addOp(alloc().create_trivial<RoundRectOp>(
-            Rect(left, top, right, bottom),
-            *(mState.currentSnapshot()->transform),
-            getRecordedClip(),
-            refPaint(&paint), rx, ry));
+    if (CC_LIKELY(MathUtils::isPositive(rx) || MathUtils::isPositive(ry))) {
+        addOp(alloc().create_trivial<RoundRectOp>(
+                Rect(left, top, right, bottom),
+                *(mState.currentSnapshot()->transform),
+                getRecordedClip(),
+                refPaint(&paint), rx, ry));
+    } else {
+        drawRect(left, top, right, bottom, paint);
+    }
 }
 
 void RecordingCanvas::drawRoundRect(
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 2e3856f..f7b38e3 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -229,19 +229,25 @@
         // No trimming necessary.
         return;
     }
+    mTrimDirty = false;
+    mTrimmedSkPath.reset();
+    if (mProperties.trimPathStart == mProperties.trimPathEnd) {
+        // Trimmed path should be empty.
+        return;
+    }
     SkPathMeasure measure(mSkPath, false);
     float len = SkScalarToFloat(measure.getLength());
     float start = len * fmod((mProperties.trimPathStart + mProperties.trimPathOffset), 1.0f);
     float end = len * fmod((mProperties.trimPathEnd + mProperties.trimPathOffset), 1.0f);
 
-    mTrimmedSkPath.reset();
     if (start > end) {
         measure.getSegment(start, len, &mTrimmedSkPath, true);
-        measure.getSegment(0, end, &mTrimmedSkPath, true);
+        if (end > 0) {
+            measure.getSegment(0, end, &mTrimmedSkPath, true);
+        }
     } else {
         measure.getSegment(start, end, &mTrimmedSkPath, true);
     }
-    mTrimDirty = false;
 }
 
 REQUIRE_COMPATIBLE_LAYOUT(FullPath::Properties);
diff --git a/libs/hwui/debug/nullgles.cpp b/libs/hwui/debug/nullgles.cpp
index ffb0649..8689f98 100644
--- a/libs/hwui/debug/nullgles.cpp
+++ b/libs/hwui/debug/nullgles.cpp
@@ -133,6 +133,15 @@
     }
 }
 
+GLenum glCheckFramebufferStatus(GLenum target) {
+    switch (target) {
+    case GL_FRAMEBUFFER:
+        return GL_FRAMEBUFFER_COMPLETE;
+    default:
+        return 0; // error case
+    }
+}
+
 const char* getString(GLenum name) {
     switch (name) {
     case GL_VENDOR:
diff --git a/libs/hwui/renderstate/OffscreenBufferPool.cpp b/libs/hwui/renderstate/OffscreenBufferPool.cpp
index 5f984b5..bb1a044 100644
--- a/libs/hwui/renderstate/OffscreenBufferPool.cpp
+++ b/libs/hwui/renderstate/OffscreenBufferPool.cpp
@@ -164,6 +164,9 @@
         // resize in place
         layer->viewportWidth = width;
         layer->viewportHeight = height;
+
+        // entire area will be repainted (and may be smaller) so clear usage region
+        layer->region.clear();
         return layer;
     }
     putOrDelete(layer);
diff --git a/libs/hwui/tests/unit/BakedOpRendererTests.cpp b/libs/hwui/tests/unit/BakedOpRendererTests.cpp
new file mode 100644
index 0000000..59bd75e
--- /dev/null
+++ b/libs/hwui/tests/unit/BakedOpRendererTests.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2016 The Android Open Source 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 <gtest/gtest.h>
+
+#include <BakedOpRenderer.h>
+#include <tests/common/TestUtils.h>
+
+using namespace android::uirenderer;
+
+const BakedOpRenderer::LightInfo sLightInfo = { 128, 128 };
+
+RENDERTHREAD_TEST(BakedOpRenderer, startRepaintLayer_clear) {
+    BakedOpRenderer renderer(Caches::getInstance(), renderThread.renderState(), true, sLightInfo);
+    OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 200u, 200u);
+
+    layer.dirty(Rect(200, 200));
+    {
+        renderer.startRepaintLayer(&layer, Rect(200, 200));
+        EXPECT_TRUE(layer.region.isEmpty()) << "Repaint full layer should clear region";
+        renderer.endLayer();
+    }
+
+    layer.dirty(Rect(200, 200));
+    {
+        renderer.startRepaintLayer(&layer, Rect(100, 200)); // repainting left side
+        EXPECT_TRUE(layer.region.isRect());
+        //ALOGD("bounds %d %d %d %d", RECT_ARGS(layer.region.getBounds()));
+        EXPECT_EQ(android::Rect(100, 0, 200, 200), layer.region.getBounds())
+                << "Left side being repainted, so right side should be clear";
+        renderer.endLayer();
+    }
+
+    // right side is now only dirty portion
+    {
+        renderer.startRepaintLayer(&layer, Rect(100, 0, 200, 200)); // repainting right side
+        EXPECT_TRUE(layer.region.isEmpty())
+                << "Now right side being repainted, so region should be entirely clear";
+        renderer.endLayer();
+    }
+}
diff --git a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
index 0c6eb57..37a485e 100644
--- a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
+++ b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
@@ -103,9 +103,11 @@
         OffscreenBufferPool pool;
 
         auto layer = pool.get(thread.renderState(), 64u, 64u);
+        layer->dirty(Rect(64, 64));
 
         // resize in place
         ASSERT_EQ(layer, pool.resize(layer, 60u, 55u));
+        EXPECT_TRUE(layer->region.isEmpty()) << "In place resize should clear usage region";
         EXPECT_EQ(60u, layer->viewportWidth);
         EXPECT_EQ(55u, layer->viewportHeight);
         EXPECT_EQ(64u, layer->texture.width());
@@ -113,9 +115,13 @@
 
         // resized to use different object in pool
         auto layer2 = pool.get(thread.renderState(), 128u, 128u);
+        layer2->dirty(Rect(128, 128));
+        EXPECT_FALSE(layer2->region.isEmpty());
         pool.putOrDelete(layer2);
         ASSERT_EQ(1u, pool.getCount());
+
         ASSERT_EQ(layer2, pool.resize(layer, 120u, 125u));
+        EXPECT_TRUE(layer2->region.isEmpty()) << "Swap resize should clear usage region";
         EXPECT_EQ(120u, layer2->viewportWidth);
         EXPECT_EQ(125u, layer2->viewportHeight);
         EXPECT_EQ(128u, layer2->texture.width());
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index c3165bb..5e613fd 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -114,6 +114,23 @@
     EXPECT_EQ(Rect(10, 20, 90, 180), op.unmappedBounds);
 }
 
+TEST(RecordingCanvas, drawRoundRect) {
+    // Round case - stays rounded
+    auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) {
+        canvas.drawRoundRect(0, 0, 100, 100, 10, 10, SkPaint());
+    });
+    ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op";
+    ASSERT_EQ(RecordedOpId::RoundRectOp, dl->getOps()[0]->opId);
+
+    // Non-rounded case - turned into drawRect
+    dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) {
+        canvas.drawRoundRect(0, 0, 100, 100, 0, -1, SkPaint());
+    });
+    ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op";
+    ASSERT_EQ(RecordedOpId::RectOp, dl->getOps()[0]->opId)
+        << "Non-rounded rects should be converted";
+}
+
 TEST(RecordingCanvas, drawText) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
         SkPaint paint;
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 3771474..0f82cfc 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -394,30 +394,48 @@
      * value here as no error checking is or can be done.
      */
     /*package*/ AudioRecord(long nativeRecordInJavaObj) {
-        int[] session = { 0 };
-        int[] rates = { 0 };
-        //TODO: update native initialization when information about hardware init failure
-        //      due to capture device already open is available.
-        // Note that for this native_setup, we are providing an already created/initialized
-        // *Native* AudioRecord, so the attributes parameters to native_setup() are ignored.
-        int initResult = native_setup(new WeakReference<AudioRecord>(this),
-                null /*mAudioAttributes*/,
-                rates /*mSampleRates*/,
-                0 /*mChannelMask*/,
-                0 /*mChannelIndexMask*/,
-                0 /*mAudioFormat*/,
-                0 /*mNativeBufferSizeInBytes*/,
-                session,
-                ActivityThread.currentOpPackageName(),
-                nativeRecordInJavaObj);
-        if (initResult != SUCCESS) {
-            loge("Error code "+initResult+" when initializing native AudioRecord object.");
-            return; // with mState == STATE_UNINITIALIZED
+        mNativeRecorderInJavaObj = 0;
+        mNativeCallbackCookie = 0;
+        mNativeDeviceCallback = 0;
+
+        // other initialization...
+        if (nativeRecordInJavaObj != 0) {
+            deferred_connect(nativeRecordInJavaObj);
+        } else {
+            mState = STATE_UNINITIALIZED;
         }
+    }
 
-        mSessionId = session[0];
+    /**
+     * @hide
+     */
+    /* package */ void deferred_connect(long  nativeRecordInJavaObj) {
+        if (mState != STATE_INITIALIZED) {
+            int[] session = { 0 };
+            int[] rates = { 0 };
+            //TODO: update native initialization when information about hardware init failure
+            //      due to capture device already open is available.
+            // Note that for this native_setup, we are providing an already created/initialized
+            // *Native* AudioRecord, so the attributes parameters to native_setup() are ignored.
+            int initResult = native_setup(new WeakReference<AudioRecord>(this),
+                    null /*mAudioAttributes*/,
+                    rates /*mSampleRates*/,
+                    0 /*mChannelMask*/,
+                    0 /*mChannelIndexMask*/,
+                    0 /*mAudioFormat*/,
+                    0 /*mNativeBufferSizeInBytes*/,
+                    session,
+                    ActivityThread.currentOpPackageName(),
+                    nativeRecordInJavaObj);
+            if (initResult != SUCCESS) {
+                loge("Error code "+initResult+" when initializing native AudioRecord object.");
+                return; // with mState == STATE_UNINITIALIZED
+            }
 
-        mState = STATE_INITIALIZED;
+            mSessionId = session[0];
+
+            mState = STATE_INITIALIZED;
+        }
     }
 
     /**
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 2aac2b3..c5d1120 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -526,11 +526,18 @@
      * the AudioTrackRoutingProxy subclass.
      * @param nativeTrackInJavaObj a C/C++ pointer to a native AudioTrack
      * (associated with an OpenSL ES player).
+     * IMPORTANT: For "N", this method is ONLY called to setup a Java routing proxy,
+     * i.e. IAndroidConfiguration::AcquireJavaProxy(). If we call with a 0 in nativeTrackInJavaObj
+     * it means that the OpenSL player interface hasn't been realized, so there is no native
+     * Audiotrack to connect to. In this case wait to call deferred_connect() until the
+     * OpenSLES interface is realized.
      */
     /*package*/ AudioTrack(long nativeTrackInJavaObj) {
         // "final"s
         mAttributes = null;
         mAppOps = null;
+        mNativeTrackInJavaObj = 0;
+        mJniData = 0;
 
         // remember which looper is associated with the AudioTrack instantiation
         Looper looper;
@@ -540,28 +547,41 @@
         mInitializationLooper = looper;
 
         // other initialization...
-        // Note that for this native_setup, we are providing an already created/initialized
-        // *Native* AudioTrack, so the attributes parameters to native_setup() are ignored.
-        int[] session = { 0 };
-        int[] rates = { 0 };
-        int initResult = native_setup(new WeakReference<AudioTrack>(this),
-                null /*mAttributes - NA*/,
-                rates /*sampleRate - NA*/,
-                0 /*mChannelMask - NA*/,
-                0 /*mChannelIndexMask - NA*/,
-                0 /*mAudioFormat - NA*/,
-                0 /*mNativeBufferSizeInBytes - NA*/,
-                0 /*mDataLoadMode - NA*/,
-                session,
-                nativeTrackInJavaObj);
-        if (initResult != SUCCESS) {
-            loge("Error code "+initResult+" when initializing AudioTrack.");
-            return; // with mState == STATE_UNINITIALIZED
+        if (nativeTrackInJavaObj != 0) {
+            deferred_connect(nativeTrackInJavaObj);
+        } else {
+            mState = STATE_UNINITIALIZED;
         }
+    }
 
-        mSessionId = session[0];
+    /**
+     * @hide
+     */
+    /* package */ void deferred_connect(long nativeTrackInJavaObj) {
+        if (mState != STATE_INITIALIZED) {
+            // Note that for this native_setup, we are providing an already created/initialized
+            // *Native* AudioTrack, so the attributes parameters to native_setup() are ignored.
+            int[] session = { 0 };
+            int[] rates = { 0 };
+            int initResult = native_setup(new WeakReference<AudioTrack>(this),
+                    null /*mAttributes - NA*/,
+                    rates /*sampleRate - NA*/,
+                    0 /*mChannelMask - NA*/,
+                    0 /*mChannelIndexMask - NA*/,
+                    0 /*mAudioFormat - NA*/,
+                    0 /*mNativeBufferSizeInBytes - NA*/,
+                    0 /*mDataLoadMode - NA*/,
+                    session,
+                    nativeTrackInJavaObj);
+            if (initResult != SUCCESS) {
+                loge("Error code "+initResult+" when initializing AudioTrack.");
+                return; // with mState == STATE_UNINITIALIZED
+            }
 
-        mState = STATE_INITIALIZED;
+            mSessionId = session[0];
+
+            mState = STATE_INITIALIZED;
+        }
     }
 
     /**
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index ce12e76..1fc236a 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -824,7 +824,13 @@
         }
 
         // Process JPEG input stream
-        getJpegAttributes(in);
+        try {
+            getJpegAttributes(in);
+        } catch (IOException e) {
+            // Ignore exceptions in order to keep the compatibility with the old versions of
+            // ExifInterface.
+            Log.w(TAG, "Invalid JPEG", e);
+        }
 
         if (DEBUG) {
             printAttributes();
@@ -1197,8 +1203,9 @@
             }
             bytesRead += 2;
             int length = dataInputStream.readUnsignedShort() - 2;
-            if (length < 0)
+            if (length < 0) {
                 throw new IOException("Invalid length");
+            }
             bytesRead += length;
             switch (marker) {
                 case MARKER_APP1: {
@@ -1221,6 +1228,9 @@
                     if (length <= 0) {
                         throw new IOException("Invalid exif");
                     }
+                    if (DEBUG) {
+                        Log.d(TAG, "readExifSegment with a byte array (length: " + length + ")");
+                    }
                     byte[] bytes = new byte[length];
                     if (dataInputStream.read(bytes) != length) {
                         throw new IOException("Invalid exif");
@@ -1309,8 +1319,9 @@
                 case MARKER_APP1: {
                     // Rewrite EXIF segment
                     int length = dataInputStream.readUnsignedShort() - 2;
-                    if (length < 0)
+                    if (length < 0) {
                         throw new IOException("Invalid length");
+                    }
                     bytesRead += 2;
                     int read;
                     while ((read = dataInputStream.read(
@@ -1331,8 +1342,9 @@
                     // Copy JPEG segment
                     int length = dataInputStream.readUnsignedShort();
                     dataOutputStream.writeUnsignedShort(length);
-                    if (length < 0)
+                    if (length < 0) {
                         throw new IOException("Invalid length");
+                    }
                     length -= 2;
                     bytesRead += 2;
                     int read;
@@ -1385,8 +1397,9 @@
         }
         firstIfdOffset -= 8;
         if (firstIfdOffset > 0) {
-            if (dataInputStream.skip(firstIfdOffset) != firstIfdOffset)
+            if (dataInputStream.skip(firstIfdOffset) != firstIfdOffset) {
                 throw new IOException("Couldn't jump to first Ifd: " + firstIfdOffset);
+            }
         }
 
         // Read primary image TIFF image file directory.
@@ -1582,8 +1595,16 @@
     // Reads image file directory, which is a tag group in EXIF.
     private void readImageFileDirectory(ByteOrderAwarenessDataInputStream dataInputStream, int hint)
             throws IOException {
+        if (dataInputStream.peek() + 2 > dataInputStream.mLength) {
+            // Return if there is no data from the offset.
+            return;
+        }
         // See JEITA CP-3451 Figure 5. page 9.
         short numberOfDirectoryEntry = dataInputStream.readShort();
+        if (dataInputStream.peek() + 12 * numberOfDirectoryEntry > dataInputStream.mLength) {
+            // Return if the size of entries is too big.
+            return;
+        }
 
         if (DEBUG) {
             Log.d(TAG, "numberOfDirectoryEntry: " + numberOfDirectoryEntry);
@@ -1595,10 +1616,25 @@
             int numberOfComponents = dataInputStream.readInt();
             long nextEntryOffset = dataInputStream.peek() + 4;  // next four bytes is for data
                                                                 // offset or value.
+            // Look up a corresponding tag from tag number
+            String tagName = (String) sExifTagMapsForReading[hint].get(tagNumber);
 
             if (DEBUG) {
-                Log.d(TAG, String.format("tagNumber: %d, dataFormat: %d, numberOfComponents: %d",
-                        tagNumber, dataFormat, numberOfComponents));
+                Log.d(TAG, String.format("hint: %d, tagNumber: %d, tagName: %s, dataFormat: %d," +
+                        "numberOfComponents: %d", hint, tagNumber, tagName, dataFormat,
+                        numberOfComponents));
+            }
+
+            if (tagName == null || dataFormat <= 0 ||
+                    dataFormat >= IFD_FORMAT_BYTES_PER_FORMAT.length) {
+                // Skip if the parsed tag number is not defined or invalid data format.
+                if (tagName == null) {
+                    Log.w(TAG, "Skip the tag entry since tag number is not defined: " + tagNumber);
+                } else {
+                    Log.w(TAG, "Skip the tag entry since data format is invalid: " + dataFormat);
+                }
+                dataInputStream.seek(nextEntryOffset);
+                continue;
             }
 
             // Read a value from data field or seek to the value offset which is stored in data
@@ -1609,19 +1645,21 @@
                 if (DEBUG) {
                     Log.d(TAG, "seek to data offset: " + offset);
                 }
-                dataInputStream.seek(offset);
-            }
-
-            // Look up a corresponding tag from tag number
-            String tagName = (String) sExifTagMapsForReading[hint].get(tagNumber);
-            // Skip if the parsed tag number is not defined.
-            if (tagName == null) {
-                dataInputStream.seek(nextEntryOffset);
-                continue;
+                if (offset + byteCount <= dataInputStream.mLength) {
+                    dataInputStream.seek(offset);
+                } else {
+                     // Skip if invalid data offset.
+                    Log.w(TAG, "Skip the tag entry since data offset is invalid: " + offset);
+                    dataInputStream.seek(nextEntryOffset);
+                    continue;
+                }
             }
 
             // Recursively parse IFD when a IFD pointer tag appears.
             int innerIfdHint = getIfdHintFromTagNumber(tagNumber);
+            if (DEBUG) {
+                Log.d(TAG, "innerIfdHint: " + innerIfdHint + " byteCount: " + byteCount);
+            }
             if (innerIfdHint >= 0) {
                 long offset = -1L;
                 // Get offset from data field
@@ -1650,9 +1688,11 @@
                 if (DEBUG) {
                     Log.d(TAG, String.format("Offset: %d, tagName: %s", offset, tagName));
                 }
-                if (offset > 0L) {
+                if (offset > 0L && offset < dataInputStream.mLength) {
                     dataInputStream.seek(offset);
                     readImageFileDirectory(dataInputStream, innerIfdHint);
+                } else {
+                    Log.w(TAG, "Skip jump into the IFD since its offset is invalid: " + offset);
                 }
 
                 dataInputStream.seek(nextEntryOffset);
@@ -1683,14 +1723,17 @@
             }
         }
 
-        long nextIfdOffset = dataInputStream.readUnsignedInt();
-        if (DEBUG) {
-            Log.d(TAG, String.format("nextIfdOffset: %d", nextIfdOffset));
-        }
-        // The next IFD offset needs to be bigger than 8 since the first IFD offset is at least 8.
-        if (nextIfdOffset > 8) {
-            dataInputStream.seek(nextIfdOffset);
-            readImageFileDirectory(dataInputStream, IFD_THUMBNAIL_HINT);
+        if (dataInputStream.peek() + 4 <= dataInputStream.mLength) {
+            long nextIfdOffset = dataInputStream.readUnsignedInt();
+            if (DEBUG) {
+                Log.d(TAG, String.format("nextIfdOffset: %d", nextIfdOffset));
+            }
+            // The next IFD offset needs to be bigger than 8
+            // since the first IFD offset is at least 8.
+            if (nextIfdOffset > 8 && nextIfdOffset < dataInputStream.mLength) {
+                dataInputStream.seek(nextIfdOffset);
+                readImageFileDirectory(dataInputStream, IFD_THUMBNAIL_HINT);
+            }
         }
     }
 
@@ -1748,17 +1791,18 @@
                 }
 
                 StringBuilder stringBuilder = new StringBuilder();
-                while (true) {
+                while (index < numberOfComponents) {
                     int ch = bytes[index];
-                    if (ch == 0)
+                    if (ch == 0) {
                         break;
-                    if (ch >= 32)
+                    }
+                    if (ch >= 32) {
                         stringBuilder.append((char) ch);
-                    else
+                    }
+                    else {
                         stringBuilder.append('?');
+                    }
                     ++index;
-                    if (index == numberOfComponents)
-                        break;
                 }
                 return stringBuilder.toString();
             }
@@ -1772,8 +1816,9 @@
     // Gets the corresponding IFD group index of the given tag number for writing Exif Tags.
     private static int getIfdHintFromTagNumber(int tagNumber) {
         for (int i = 0; i < IFD_POINTER_TAG_HINTS.length; ++i) {
-            if (IFD_POINTER_TAGS[i].number == tagNumber)
+            if (IFD_POINTER_TAGS[i].number == tagNumber) {
                 return IFD_POINTER_TAG_HINTS[i];
+            }
         }
         return -1;
     }
@@ -2076,8 +2121,9 @@
         public void seek(long byteCount) throws IOException {
             mPosition = 0L;
             reset();
-            if (skip(byteCount) != byteCount)
+            if (skip(byteCount) != byteCount) {
                 throw new IOException("Couldn't seek up to the byteCount");
+            }
         }
 
         public long peek() {
@@ -2086,8 +2132,9 @@
 
         public void readFully(byte[] buffer) throws IOException {
             mPosition += buffer.length;
-            if (mPosition > mLength)
+            if (mPosition > mLength) {
                 throw new EOFException();
+            }
             if (super.read(buffer, 0, buffer.length) != buffer.length) {
                 throw new IOException("Couldn't read up to the length of buffer");
             }
@@ -2095,22 +2142,26 @@
 
         public byte readByte() throws IOException {
             ++mPosition;
-            if (mPosition > mLength)
+            if (mPosition > mLength) {
                 throw new EOFException();
+            }
             int ch = super.read();
-            if (ch < 0)
+            if (ch < 0) {
                 throw new EOFException();
+            }
             return (byte) ch;
         }
 
         public short readShort() throws IOException {
             mPosition += 2;
-            if (mPosition > mLength)
+            if (mPosition > mLength) {
                 throw new EOFException();
+            }
             int ch1 = super.read();
             int ch2 = super.read();
-            if ((ch1 | ch2) < 0)
+            if ((ch1 | ch2) < 0) {
                 throw new EOFException();
+            }
             if (mByteOrder == LITTLE_ENDIAN) {
                 return (short) ((ch2 << 8) + (ch1));
             } else if (mByteOrder == BIG_ENDIAN) {
@@ -2121,14 +2172,16 @@
 
         public int readInt() throws IOException {
             mPosition += 4;
-            if (mPosition > mLength)
+            if (mPosition > mLength) {
                 throw new EOFException();
+            }
             int ch1 = super.read();
             int ch2 = super.read();
             int ch3 = super.read();
             int ch4 = super.read();
-            if ((ch1 | ch2 | ch3 | ch4) < 0)
+            if ((ch1 | ch2 | ch3 | ch4) < 0) {
                 throw new EOFException();
+            }
             if (mByteOrder == LITTLE_ENDIAN) {
                 return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + ch1);
             } else if (mByteOrder == BIG_ENDIAN) {
@@ -2146,12 +2199,14 @@
 
         public int readUnsignedShort() throws IOException {
             mPosition += 2;
-            if (mPosition > mLength)
+            if (mPosition > mLength) {
                 throw new EOFException();
+            }
             int ch1 = super.read();
             int ch2 = super.read();
-            if ((ch1 | ch2) < 0)
+            if ((ch1 | ch2) < 0) {
                 throw new EOFException();
+            }
             if (mByteOrder == LITTLE_ENDIAN) {
                 return ((ch2 << 8) + (ch1));
             } else if (mByteOrder == BIG_ENDIAN) {
@@ -2166,8 +2221,9 @@
 
         public long readLong() throws IOException {
             mPosition += 8;
-            if (mPosition > mLength)
+            if (mPosition > mLength) {
                 throw new EOFException();
+            }
             int ch1 = super.read();
             int ch2 = super.read();
             int ch3 = super.read();
@@ -2176,8 +2232,9 @@
             int ch6 = super.read();
             int ch7 = super.read();
             int ch8 = super.read();
-            if ((ch1 | ch2 | ch3 | ch4 | ch5 | ch6 | ch7 | ch8) < 0)
+            if ((ch1 | ch2 | ch3 | ch4 | ch5 | ch6 | ch7 | ch8) < 0) {
                 throw new EOFException();
+            }
             if (mByteOrder == LITTLE_ENDIAN) {
                 return (((long) ch8 << 56) + ((long) ch7 << 48) + ((long) ch6 << 40)
                         + ((long) ch5 << 32) + ((long) ch4 << 24) + ((long) ch3 << 16)
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index db0c5bb..2650ee0 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -1070,16 +1070,15 @@
      * A CryptoSession is obtained using {@link #getCryptoSession}
      */
     public final class CryptoSession {
-        private MediaDrm mDrm;
         private byte[] mSessionId;
 
-        CryptoSession(@NonNull MediaDrm drm, @NonNull byte[] sessionId,
-                @NonNull String cipherAlgorithm, @NonNull String macAlgorithm)
+        CryptoSession(@NonNull byte[] sessionId,
+                      @NonNull String cipherAlgorithm,
+                      @NonNull String macAlgorithm)
         {
             mSessionId = sessionId;
-            mDrm = drm;
-            setCipherAlgorithmNative(drm, sessionId, cipherAlgorithm);
-            setMacAlgorithmNative(drm, sessionId, macAlgorithm);
+            setCipherAlgorithmNative(MediaDrm.this, sessionId, cipherAlgorithm);
+            setMacAlgorithmNative(MediaDrm.this, sessionId, macAlgorithm);
         }
 
         /**
@@ -1092,7 +1091,7 @@
         @NonNull
         public byte[] encrypt(
                 @NonNull byte[] keyid, @NonNull byte[] input, @NonNull byte[] iv) {
-            return encryptNative(mDrm, mSessionId, keyid, input, iv);
+            return encryptNative(MediaDrm.this, mSessionId, keyid, input, iv);
         }
 
         /**
@@ -1105,7 +1104,7 @@
         @NonNull
         public byte[] decrypt(
                 @NonNull byte[] keyid, @NonNull byte[] input, @NonNull byte[] iv) {
-            return decryptNative(mDrm, mSessionId, keyid, input, iv);
+            return decryptNative(MediaDrm.this, mSessionId, keyid, input, iv);
         }
 
         /**
@@ -1116,7 +1115,7 @@
          */
         @NonNull
         public byte[] sign(@NonNull byte[] keyid, @NonNull byte[] message) {
-            return signNative(mDrm, mSessionId, keyid, message);
+            return signNative(MediaDrm.this, mSessionId, keyid, message);
         }
 
         /**
@@ -1130,7 +1129,7 @@
          */
         public boolean verify(
                 @NonNull byte[] keyid, @NonNull byte[] message, @NonNull byte[] signature) {
-            return verifyNative(mDrm, mSessionId, keyid, message, signature);
+            return verifyNative(MediaDrm.this, mSessionId, keyid, message, signature);
         }
     };
 
@@ -1158,7 +1157,7 @@
             @NonNull byte[] sessionId,
             @NonNull String cipherAlgorithm, @NonNull String macAlgorithm)
     {
-        return new CryptoSession(this, sessionId, cipherAlgorithm, macAlgorithm);
+        return new CryptoSession(sessionId, cipherAlgorithm, macAlgorithm);
     }
 
     /**
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 0b0306c..89e4577 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.graphics.Rect;
 import android.media.PlaybackParams;
@@ -1241,6 +1242,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PARENTAL_CONTROLS)
     public void setParentalControlsEnabled(boolean enabled) {
         try {
             mService.setParentalControlsEnabled(enabled, mUserId);
@@ -1292,6 +1294,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PARENTAL_CONTROLS)
     public void addBlockedRating(@NonNull TvContentRating rating) {
         Preconditions.checkNotNull(rating);
         try {
@@ -1310,6 +1313,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PARENTAL_CONTROLS)
     public void removeBlockedRating(@NonNull TvContentRating rating) {
         Preconditions.checkNotNull(rating);
         try {
@@ -1444,6 +1448,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
     public List<TvInputHardwareInfo> getHardwareList() {
         try {
             return mService.getHardwareList();
@@ -1462,6 +1467,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
     public Hardware acquireTvInputHardware(int deviceId, final HardwareCallback callback,
             TvInputInfo info) {
         try {
@@ -1488,6 +1494,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
     public void releaseTvInputHardware(int deviceId, Hardware hardware) {
         try {
             mService.releaseTvInputHardware(deviceId, hardware.getInterface(), mUserId);
diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp
index 527e6c2..62685c9 100644
--- a/media/jni/android_media_Utils.cpp
+++ b/media/jni/android_media_Utils.cpp
@@ -307,6 +307,11 @@
         AMessage::Type valueType;
         const char *key = msg->getEntryNameAt(i, &valueType);
 
+        if (!strncmp(key, "android._", 9)) {
+            // don't expose private keys (starting with android._)
+            continue;
+        }
+
         jobject valueObj = NULL;
 
         switch (valueType) {
@@ -460,6 +465,11 @@
         env->ReleaseStringUTFChars((jstring)keyObj, tmp);
         tmp = NULL;
 
+        if (key.startsWith("android._")) {
+            // don't propagate private keys (starting with android._)
+            continue;
+        }
+
         jobject valueObj = env->GetObjectArrayElement(values, i);
 
         if (env->IsInstanceOf(valueObj, stringClass.get())) {
@@ -735,8 +745,15 @@
         case HAL_PIXEL_FORMAT_BLOB:
             // Used for JPEG data, height must be 1, width == size, single plane.
             LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx);
-            LOG_ALWAYS_FATAL_IF(buffer->height != 1,
-                    "BLOB format buffer should has height value %d", buffer->height);
+            // When RGBA override is being used, buffer height will be equal to width
+            if (usingRGBAOverride) {
+                LOG_ALWAYS_FATAL_IF(buffer->height != buffer->width,
+                        "RGBA override BLOB format buffer should have height == width");
+            } else {
+                LOG_ALWAYS_FATAL_IF(buffer->height != 1,
+                        "BLOB format buffer should have height value 1");
+            }
+
 
             pData = buffer->data;
             dataSize = Image_getJpegSize(buffer, usingRGBAOverride);
diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml
index 6f38e25..6fe239e 100644
--- a/packages/DocumentsUI/AndroidManifest.xml
+++ b/packages/DocumentsUI/AndroidManifest.xml
@@ -5,6 +5,8 @@
     <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
     <uses-permission android:name="android.permission.REMOVE_TASKS" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.CACHE_CONTENT" />
+    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
 
     <application
         android:name=".DocumentsApplication"
@@ -105,6 +107,12 @@
             </intent-filter>
         </receiver>
 
+        <receiver android:name=".BootReceiver">
+            <intent-filter>
+                <action android:name="android.intent.action.BOOT_COMPLETED" />
+            </intent-filter>
+        </receiver>
+
         <service
             android:name=".services.FileOperationService"
             android:exported="false">
diff --git a/packages/DocumentsUI/res/layout/dialog_open_scoped_directory.xml b/packages/DocumentsUI/res/layout/dialog_open_scoped_directory.xml
new file mode 100644
index 0000000..d4a450b
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/dialog_open_scoped_directory.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:paddingEnd="24dp"
+    android:paddingStart="24dp" >
+
+    <TextView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/message"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:paddingEnd="24dp"
+        android:paddingStart="24dp"
+        android:paddingTop="24dp"
+        android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+        android:textColor="@*android:color/primary_text_default_material_light" >
+    </TextView>
+
+    <CheckBox
+        android:id="@+id/do_not_ask_checkbox"
+        style="?android:attr/textAppearanceSmall"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dip"
+        android:text="@string/never_ask_again"
+        android:visibility="gone" />
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/DocumentsUI/res/values/strings.xml b/packages/DocumentsUI/res/values/strings.xml
index e2d1870..e7406e68 100644
--- a/packages/DocumentsUI/res/values/strings.xml
+++ b/packages/DocumentsUI/res/values/strings.xml
@@ -200,10 +200,12 @@
          during a copy. [CHAR LIMIT=48] -->
     <string name="notification_copy_files_converted_title">Some files were converted</string>
 
-    <!--  DO NOT TRANSLATE - final phrase has not been decided yet (b/26750152) -->
+    <!-- Text in an alert dialog asking user to grant app access to a given directory in an external storage volume -->
     <string name="open_external_dialog_request">Grant <xliff:g id="appName" example="System Settings"><b>^1</b></xliff:g>
-        access to <xliff:g id="directory" example="Pictures"><i>^2</i></xliff:g> folder on
+        access to <xliff:g id="directory" example="Pictures"><i>^2</i></xliff:g> directory on
         <xliff:g id="storage" example="SD Card"><i>^3</i></xliff:g>?</string>
+    <!-- Checkbox that allows user to not be questioned about the directory access request again -->
+    <string name="never_ask_again">Don\'t ask again</string>
     <!-- Text in the button asking user to allow access to a given directory. -->
     <string name="allow">Allow</string>
     <!-- Text in the button asking user to deny access to a given directory. -->
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BootReceiver.java b/packages/DocumentsUI/src/com/android/documentsui/BootReceiver.java
new file mode 100644
index 0000000..cdea9d7
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/BootReceiver.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 The Android Open Source 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.documentsui;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * Prime {@link RootsCache} when the system is booted.
+ */
+public class BootReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        // We already spun up our application object before getting here, which
+        // kicked off a task to load roots, so this broadcast is finished once
+        // that first pass is done.
+        DocumentsApplication.getRootsCache(context).setBootCompletedResult(goAsync());
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/LocalPreferences.java b/packages/DocumentsUI/src/com/android/documentsui/LocalPreferences.java
index c7c61c3..8c4859f 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/LocalPreferences.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/LocalPreferences.java
@@ -16,10 +16,20 @@
 
 package com.android.documentsui;
 
+import static com.android.documentsui.Shared.DEBUG;
+import static com.android.documentsui.Shared.TAG;
 import static com.android.documentsui.State.MODE_UNKNOWN;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
 import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.UserHandle;
 import android.preference.PreferenceManager;
+import android.util.Log;
 
 import com.android.documentsui.State.ViewMode;
 import com.android.documentsui.model.RootInfo;
@@ -29,29 +39,73 @@
     private static final String ROOT_VIEW_MODE_PREFIX = "rootViewMode-";
 
     public static boolean getDisplayFileSize(Context context) {
-        return PreferenceManager.getDefaultSharedPreferences(context)
-                .getBoolean(KEY_FILE_SIZE, false);
+        return getPrefs(context).getBoolean(KEY_FILE_SIZE, false);
     }
 
-    public static @ViewMode int getViewMode(
-            Context context, RootInfo root, @ViewMode int fallback) {
-        return PreferenceManager.getDefaultSharedPreferences(context)
-                .getInt(createKey(root), fallback);
+    public static @ViewMode int getViewMode(Context context, RootInfo root,
+            @ViewMode int fallback) {
+        return getPrefs(context).getInt(createKey(root), fallback);
     }
 
     public static void setDisplayFileSize(Context context, boolean display) {
-        PreferenceManager.getDefaultSharedPreferences(context).edit()
-                .putBoolean(KEY_FILE_SIZE, display).apply();
+        getPrefs(context).edit().putBoolean(KEY_FILE_SIZE, display).apply();
     }
 
     public static void setViewMode(Context context, RootInfo root, @ViewMode int viewMode) {
         assert(viewMode != MODE_UNKNOWN);
 
-        PreferenceManager.getDefaultSharedPreferences(context).edit()
-                .putInt(createKey(root), viewMode).apply();
+        getPrefs(context).edit().putInt(createKey(root), viewMode).apply();
+    }
+
+    private static SharedPreferences getPrefs(Context context) {
+        return PreferenceManager.getDefaultSharedPreferences(context);
     }
 
     private static String createKey(RootInfo root) {
         return ROOT_VIEW_MODE_PREFIX + root.authority + root.rootId;
     }
+
+    public static final int PERMISSION_ASK = 0;
+    public static final int PERMISSION_ASK_AGAIN = 1;
+    public static final int PERMISSION_NEVER_ASK = -1;
+
+    @IntDef(flag = true, value = {
+            PERMISSION_ASK,
+            PERMISSION_ASK_AGAIN,
+            PERMISSION_NEVER_ASK,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PermissionStatus {}
+
+    /**
+     * Methods below are used to keep track of denied user requests on scoped directory access so
+     * the dialog is not offered when user checked the 'Do not ask again' box
+     *
+     * <p>It uses a shared preferences, whose key is:
+     * <ol>
+     * <li>{@code USER_ID|PACKAGE_NAME|VOLUME_UUID|DIRECTORY} for storage volumes that have a UUID
+     * (typically physical volumes like SD cards).
+     * <li>{@code USER_ID|PACKAGE_NAME||DIRECTORY} for storage volumes that do not have a UUID
+     * (typically the emulated volume used for primary storage
+     * </ol>
+     */
+    static @PermissionStatus int getScopedAccessPermissionStatus(Context context,
+            String packageName, @Nullable String uuid, String directory) {
+        final String key = getScopedAccessDenialsKey(packageName, uuid, directory);
+        return getPrefs(context).getInt(key, PERMISSION_ASK);
+    }
+
+    static void setScopedAccessPermissionStatus(Context context, String packageName,
+            @Nullable String uuid, String directory, @PermissionStatus int status) {
+      final String key = getScopedAccessDenialsKey(packageName, uuid, directory);
+      getPrefs(context).edit().putInt(key, status).apply();
+    }
+
+    private static String getScopedAccessDenialsKey(String packageName, String uuid,
+            String directory) {
+        final int userId = UserHandle.myUserId();
+        return uuid == null
+                ? userId + "|" + packageName + "||" + directory
+                : userId + "|" + packageName + "|" + uuid + "|" + directory;
+    }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
index afd308c..deef1c2 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
@@ -411,11 +411,15 @@
     public static final int SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED = 0;
     public static final int SCOPED_DIRECTORY_ACCESS_GRANTED = 1;
     public static final int SCOPED_DIRECTORY_ACCESS_DENIED = 2;
+    public static final int SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST = 3;
+    public static final int SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED = 4;
 
     @IntDef(flag = true, value = {
             SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED,
             SCOPED_DIRECTORY_ACCESS_GRANTED,
-            SCOPED_DIRECTORY_ACCESS_DENIED
+            SCOPED_DIRECTORY_ACCESS_DENIED,
+            SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST,
+            SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ScopedAccessGrant {}
@@ -432,23 +436,34 @@
         final String packageName = activity.getCallingPackage();
         switch (type) {
             case SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED:
-                MetricsLogger.action(activity,
-                        MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_PACKAGE,
-                        packageName);
-                MetricsLogger.action(activity,
-                        MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_FOLDER, index);
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_PACKAGE, packageName);
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_FOLDER, index);
                 break;
             case SCOPED_DIRECTORY_ACCESS_GRANTED:
-                MetricsLogger.action(activity,
-                        MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_PACKAGE, packageName);
-                MetricsLogger.action(activity,
-                        MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_FOLDER, index);
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_PACKAGE, packageName);
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_FOLDER, index);
                 break;
             case SCOPED_DIRECTORY_ACCESS_DENIED:
-                MetricsLogger.action(activity,
-                        MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_PACKAGE, packageName);
-                MetricsLogger.action(activity,
-                        MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_FOLDER, index);
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_PACKAGE, packageName);
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_FOLDER, index);
+                break;
+            case SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST:
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST_BY_PACKAGE, packageName);
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST_BY_FOLDER, index);
+                break;
+            case SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED:
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED_BY_PACKAGE, packageName);
+                MetricsLogger.action(activity, MetricsEvent
+                        .ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED_BY_FOLDER, index);
                 break;
             default:
                 Log.wtf(TAG, "invalid ScopedAccessGrant: " + type);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/OpenExternalDirectoryActivity.java b/packages/DocumentsUI/src/com/android/documentsui/OpenExternalDirectoryActivity.java
index dc529ce..f30ab23 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/OpenExternalDirectoryActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/OpenExternalDirectoryActivity.java
@@ -20,16 +20,24 @@
 import static android.os.Environment.STANDARD_DIRECTORIES;
 import static android.os.storage.StorageVolume.EXTRA_DIRECTORY_NAME;
 import static android.os.storage.StorageVolume.EXTRA_STORAGE_VOLUME;
-import static com.android.documentsui.Shared.DEBUG;
-import static com.android.documentsui.Metrics.logInvalidScopedAccessRequest;
-import static com.android.documentsui.Metrics.logValidScopedAccessRequest;
+import static com.android.documentsui.LocalPreferences.getScopedAccessPermissionStatus;
+import static com.android.documentsui.LocalPreferences.PERMISSION_ASK;
+import static com.android.documentsui.LocalPreferences.PERMISSION_ASK_AGAIN;
+import static com.android.documentsui.LocalPreferences.PERMISSION_NEVER_ASK;
+import static com.android.documentsui.LocalPreferences.setScopedAccessPermissionStatus;
+import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED;
 import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED;
 import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_DENIED;
+import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST;
 import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_ERROR;
 import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_GRANTED;
 import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS;
 import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY;
+import static com.android.documentsui.Metrics.logInvalidScopedAccessRequest;
+import static com.android.documentsui.Metrics.logValidScopedAccessRequest;
+import static com.android.documentsui.Shared.DEBUG;
 
+import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.AlertDialog;
@@ -38,7 +46,6 @@
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
 import android.content.ContentProviderClient;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
@@ -57,6 +64,11 @@
 import android.provider.DocumentsContract;
 import android.text.TextUtils;
 import android.util.Log;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.TextView;
 
 import java.io.File;
 import java.io.IOException;
@@ -72,12 +84,17 @@
     private static final String EXTRA_FILE = "com.android.documentsui.FILE";
     private static final String EXTRA_APP_LABEL = "com.android.documentsui.APP_LABEL";
     private static final String EXTRA_VOLUME_LABEL = "com.android.documentsui.VOLUME_LABEL";
+    private static final String EXTRA_VOLUME_UUID = "com.android.documentsui.VOLUME_UUID";
 
     private ContentProviderClient mExternalStorageClient;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        if (savedInstanceState != null) {
+            if (DEBUG) Log.d(TAG, "activity.onCreateDialog(): reusing instance");
+            return;
+        }
 
         final Intent intent = getIntent();
         if (intent == null) {
@@ -105,9 +122,18 @@
             finish();
             return;
         }
+        final StorageVolume volume = (StorageVolume) storageVolume;
+        if (getScopedAccessPermissionStatus(getApplicationContext(), getCallingPackage(),
+                volume.getUuid(), directoryName) == PERMISSION_NEVER_ASK) {
+            logValidScopedAccessRequest(this, directoryName,
+                    SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED);
+            setResult(RESULT_CANCELED);
+            finish();
+            return;
+        }
 
         final int userId = UserHandle.myUserId();
-        if (!showFragment(this, userId, (StorageVolume) storageVolume, directoryName)) {
+        if (!showFragment(this, userId, volume, directoryName)) {
             setResult(RESULT_CANCELED);
             finish();
             return;
@@ -157,6 +183,7 @@
 
         // Gets volume label and converted path.
         String volumeLabel = null;
+        String volumeUuid = null;
         final List<VolumeInfo> volumes = sm.getVolumes();
         if (DEBUG) Log.d(TAG, "Number of volumes: " + volumes.size());
         for (VolumeInfo volume : volumes) {
@@ -166,6 +193,7 @@
                 if (DEBUG) Log.d(TAG, "Converting " + root + " to " + internalRoot);
                 file = new File(internalRoot, directory);
                 volumeLabel = sm.getBestVolumeDescription(volume);
+                volumeUuid = volume.getFsUuid();
                 break;
             }
         }
@@ -197,6 +225,7 @@
         final Bundle args = new Bundle();
         args.putString(EXTRA_FILE, file.getAbsolutePath());
         args.putString(EXTRA_VOLUME_LABEL, volumeLabel);
+        args.putString(EXTRA_VOLUME_UUID, volumeUuid);
         args.putString(EXTRA_APP_LABEL, appLabel);
 
         final FragmentManager fm = activity.getFragmentManager();
@@ -303,16 +332,21 @@
     public static class OpenExternalDirectoryDialogFragment extends DialogFragment {
 
         private File mFile;
+        private String mVolumeUuid;
         private String mVolumeLabel;
         private String mAppLabel;
+        private CheckBox mDontAskAgain;
         private OpenExternalDirectoryActivity mActivity;
+        private AlertDialog mDialog;
 
         @Override
         public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
+            setRetainInstance(true);
             final Bundle args = getArguments();
             if (args != null) {
                 mFile = new File(args.getString(EXTRA_FILE));
+                mVolumeUuid = args.getString(EXTRA_VOLUME_UUID);
                 mVolumeLabel = args.getString(EXTRA_VOLUME_LABEL);
                 mAppLabel = args.getString(EXTRA_APP_LABEL);
             }
@@ -320,9 +354,28 @@
         }
 
         @Override
+        public void onDestroyView() {
+            // Workaround for https://code.google.com/p/android/issues/detail?id=17423
+            if (mDialog != null && getRetainInstance()) {
+                mDialog.setDismissMessage(null);
+            }
+            super.onDestroyView();
+        }
+
+        @Override
         public Dialog onCreateDialog(Bundle savedInstanceState) {
+            if (mDialog != null) {
+                if (DEBUG) Log.d(TAG, "fragment.onCreateDialog(): reusing dialog");
+                return mDialog;
+            }
+            if (mActivity != getActivity()) {
+                // Sanity check.
+                Log.wtf(TAG, "activity references don't match on onCreateDialog(): mActivity = "
+                        + mActivity + " , getActivity() = " + getActivity());
+                mActivity = (OpenExternalDirectoryActivity) getActivity();
+            }
             final String directory = mFile.getName();
-            final Activity activity = getActivity();
+            final Context context = mActivity.getApplicationContext();
             final OnClickListener listener = new OnClickListener() {
 
                 @Override
@@ -333,15 +386,25 @@
                                 mActivity.getExternalStorageClient(), mFile);
                     }
                     if (which == DialogInterface.BUTTON_NEGATIVE || intent == null) {
-                        logValidScopedAccessRequest(activity, directory,
+                        logValidScopedAccessRequest(mActivity, directory,
                                 SCOPED_DIRECTORY_ACCESS_DENIED);
-                        activity.setResult(RESULT_CANCELED);
+                        final boolean checked = mDontAskAgain.isChecked();
+                        if (checked) {
+                            logValidScopedAccessRequest(mActivity, directory,
+                                    SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST);
+                            setScopedAccessPermissionStatus(context, mActivity.getCallingPackage(),
+                                    mVolumeUuid, directory, PERMISSION_NEVER_ASK);
+                        } else {
+                            setScopedAccessPermissionStatus(context, mActivity.getCallingPackage(),
+                                    mVolumeUuid, directory, PERMISSION_ASK_AGAIN);
+                        }
+                        mActivity.setResult(RESULT_CANCELED);
                     } else {
-                        logValidScopedAccessRequest(activity, directory,
+                        logValidScopedAccessRequest(mActivity, directory,
                                 SCOPED_DIRECTORY_ACCESS_GRANTED);
-                        activity.setResult(RESULT_OK, intent);
+                        mActivity.setResult(RESULT_OK, intent);
                     }
-                    activity.finish();
+                    mActivity.finish();
                 }
             };
 
@@ -349,11 +412,31 @@
                     .expandTemplate(
                             getText(R.string.open_external_dialog_request), mAppLabel, directory,
                             mVolumeLabel);
-            return new AlertDialog.Builder(activity, R.style.AlertDialogTheme)
-                    .setMessage(message)
+            @SuppressLint("InflateParams")
+            // It's ok pass null ViewRoot on AlertDialogs.
+            final View view = View.inflate(mActivity, R.layout.dialog_open_scoped_directory, null);
+            final TextView messageField = (TextView) view.findViewById(R.id.message);
+            messageField.setText(message);
+            mDialog = new AlertDialog.Builder(mActivity, R.style.AlertDialogTheme)
+                    .setView(view)
                     .setPositiveButton(R.string.allow, listener)
                     .setNegativeButton(R.string.deny, listener)
                     .create();
+
+            mDontAskAgain = (CheckBox) view.findViewById(R.id.do_not_ask_checkbox);
+            if (getScopedAccessPermissionStatus(context, mActivity.getCallingPackage(),
+                    mVolumeUuid, directory) == PERMISSION_ASK_AGAIN) {
+                mDontAskAgain.setVisibility(View.VISIBLE);
+                mDontAskAgain.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+
+                    @Override
+                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                        mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(!isChecked);
+                    }
+                });
+            }
+
+            return mDialog;
         }
 
         @Override
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
index 2b7294a..6efe9c8 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -18,6 +18,7 @@
 
 import static com.android.documentsui.Shared.DEBUG;
 
+import android.content.BroadcastReceiver.PendingResult;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -30,6 +31,7 @@
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.AsyncTask;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.SystemClock;
 import android.provider.DocumentsContract;
@@ -40,11 +42,11 @@
 import com.android.documentsui.model.RootInfo;
 import com.android.internal.annotations.GuardedBy;
 
+import libcore.io.IoUtils;
+
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Multimap;
 
-import libcore.io.IoUtils;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -63,6 +65,8 @@
 
     private static final String TAG = "RootsCache";
 
+    private static final boolean ENABLE_SYSTEM_CACHE = true;
+
     private final Context mContext;
     private final ContentObserver mObserver;
     private OnCacheUpdateListener mCacheUpdateListener;
@@ -73,6 +77,11 @@
     private final CountDownLatch mFirstLoad = new CountDownLatch(1);
 
     @GuardedBy("mLock")
+    private boolean mFirstLoadDone;
+    @GuardedBy("mLock")
+    private PendingResult mBootCompletedResult;
+
+    @GuardedBy("mLock")
     private Multimap<String, RootInfo> mRoots = ArrayListMultimap.create();
     @GuardedBy("mLock")
     private HashSet<String> mStoppedAuthorities = new HashSet<>();
@@ -118,7 +127,7 @@
     public void updateAsync() {
 
         // NOTE: This method is called when the UI language changes.
-        // For that reason we upadte our RecentsRoot to reflect
+        // For that reason we update our RecentsRoot to reflect
         // the current language.
         mRecentsRoot.title = mContext.getString(R.string.root_recent);
 
@@ -152,7 +161,25 @@
         }
     }
 
-    private void waitForFirstLoad() {
+    public void setBootCompletedResult(PendingResult result) {
+        synchronized (mLock) {
+            // Quickly check if we've already finished loading, otherwise hang
+            // out until first pass is finished.
+            if (mFirstLoadDone) {
+                result.finish();
+            } else {
+                mBootCompletedResult = result;
+            }
+        }
+    }
+
+    /**
+     * Block until the first {@link UpdateTask} pass has finished.
+     *
+     * @return {@code true} if cached roots is ready to roll, otherwise
+     *         {@code false} if we timed out while waiting.
+     */
+    private boolean waitForFirstLoad() {
         boolean success = false;
         try {
             success = mFirstLoad.await(15, TimeUnit.SECONDS);
@@ -161,6 +188,7 @@
         if (!success) {
             Log.w(TAG, "Timeout waiting for first update");
         }
+        return success;
     }
 
     /**
@@ -222,9 +250,11 @@
             final long start = SystemClock.elapsedRealtime();
 
             if (mFilterPackage != null) {
-                // Need at least first load, since we're going to be using
-                // previously cached values for non-matching packages.
-                waitForFirstLoad();
+                // We must have previously cached values to fill in non-matching
+                // packages, so wait around for successful first load.
+                if (!waitForFirstLoad()) {
+                    return null;
+                }
             }
 
             mTaskRoots.put(mRecentsRoot.authority, mRecentsRoot);
@@ -243,6 +273,11 @@
             if (DEBUG)
                 Log.d(TAG, "Update found " + mTaskRoots.size() + " roots in " + delta + "ms");
             synchronized (mLock) {
+                mFirstLoadDone = true;
+                if (mBootCompletedResult != null) {
+                    mBootCompletedResult.finish();
+                    mBootCompletedResult = null;
+                }
                 mRoots = mTaskRoots;
                 mStoppedAuthorities = mTaskStoppedAuthorities;
             }
@@ -300,9 +335,18 @@
             }
         }
 
-        final List<RootInfo> roots = new ArrayList<>();
         final Uri rootsUri = DocumentsContract.buildRootsUri(authority);
+        if (ENABLE_SYSTEM_CACHE) {
+            // Look for roots data that we might have cached for ourselves in the
+            // long-lived system process.
+            final Bundle systemCache = resolver.getCache(rootsUri);
+            if (systemCache != null) {
+                if (DEBUG) Log.d(TAG, "System cache hit for " + authority);
+                return systemCache.getParcelableArrayList(TAG);
+            }
+        }
 
+        final ArrayList<RootInfo> roots = new ArrayList<>();
         ContentProviderClient client = null;
         Cursor cursor = null;
         try {
@@ -318,6 +362,16 @@
             IoUtils.closeQuietly(cursor);
             ContentProviderClient.releaseQuietly(client);
         }
+
+        if (ENABLE_SYSTEM_CACHE) {
+            // Cache these freshly parsed roots over in the long-lived system
+            // process, in case our process goes away. The system takes care of
+            // invalidating the cache if the package or Uri changes.
+            final Bundle systemCache = new Bundle();
+            systemCache.putParcelableArrayList(TAG, roots);
+            resolver.putCache(rootsUri, systemCache);
+        }
+
         return roots;
     }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Shared.java b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
index 26900a7..b539421 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Shared.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
@@ -86,12 +86,6 @@
      */
     public static final String EXTRA_IGNORE_STATE = "ignoreState";
 
-
-    /**
-     * String prefix used to indicate the document is a directory.
-     */
-    public static final char DIR_PREFIX = '\001';
-
     private static final Collator sCollator;
 
     static {
@@ -150,12 +144,6 @@
         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/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index bfc8d71..be70417 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -440,6 +440,7 @@
 
         private Selection mSelected = new Selection();
         private ActionMode mActionMode;
+        private int mNoCopyCount = 0;
         private int mNoDeleteCount = 0;
         private int mNoRenameCount = -1;
         private Menu mMenu;
@@ -471,6 +472,9 @@
             // triggered on "silent" selection updates (i.e. we might be reacting to unfinalized
             // selection changes here)
             final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
+            if ((docFlags & Document.FLAG_PARTIAL) != 0) {
+                mNoCopyCount += selected ? 1 : -1;
+            }
             if ((docFlags & Document.FLAG_SUPPORTS_DELETE) == 0
                     && (docFlags & Document.FLAG_SUPPORTS_DELETE) == 0) {
                 mNoDeleteCount += selected ? 1 : -1;
@@ -537,19 +541,24 @@
             return true;
         }
 
-        boolean canRenameSelection() {
-            return mNoRenameCount == 0 && mSelectionManager.getSelection().size() == 1;
+        boolean canCopySelection() {
+            return mNoCopyCount == 0;
         }
 
         boolean canDeleteSelection() {
             return mNoDeleteCount == 0;
         }
 
+        boolean canRenameSelection() {
+            return mNoRenameCount == 0 && mSelectionManager.getSelection().size() == 1;
+        }
+
         private void updateActionMenu() {
             assert(mMenu != null);
 
             // Delegate update logic to our owning action, since specialized logic is desired.
-            mTuner.updateActionMenu(mMenu, mType, canDeleteSelection(), canRenameSelection());
+            mTuner.updateActionMenu(
+                    mMenu, mType, canCopySelection(), canDeleteSelection(), canRenameSelection());
             Menus.disableHiddenItems(mMenu);
         }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
index 0ee7623..39fdf8e 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
@@ -58,9 +58,9 @@
         }
     }
 
-
     public abstract void updateActionMenu(
-            Menu menu, @ResultType int dirType, boolean canDelete, boolean canRename);
+            Menu menu, @ResultType int dirType,
+            boolean canCopy, boolean canDelete, boolean canRename);
 
     // Subtly different from isDocumentEnabled. The reason may be illuminated as follows.
     // A folder is enabled such that it may be double clicked, even in settings
@@ -140,7 +140,8 @@
 
         @Override
         public void updateActionMenu(
-                Menu menu, @ResultType int dirType, boolean canDelete, boolean canRename) {
+                Menu menu, @ResultType int dirType,
+                boolean canCopy, boolean canDelete, boolean canRename) {
 
             MenuItem open = menu.findItem(R.id.menu_open);
             MenuItem share = menu.findItem(R.id.menu_share);
@@ -198,22 +199,28 @@
 
         @Override
         public void updateActionMenu(
-                Menu menu, @ResultType int dirType, boolean canDelete, boolean canRename) {
+                Menu menu, @ResultType int dirType,
+                boolean canCopy, boolean canDelete, boolean canRename) {
 
             MenuItem copy = menu.findItem(R.id.menu_copy_to_clipboard);
             MenuItem paste = menu.findItem(R.id.menu_paste_from_clipboard);
-            copy.setEnabled(dirType != DirectoryFragment.TYPE_RECENT_OPEN);
+            copy.setEnabled(canCopy);
 
             MenuItem rename = menu.findItem(R.id.menu_rename);
+            MenuItem moveTo = menu.findItem(R.id.menu_move_to);
+            MenuItem copyTo = menu.findItem(R.id.menu_copy_to);
+
+            copyTo.setVisible(true);
+            moveTo.setVisible(true);
             rename.setVisible(true);
+
+            copyTo.setEnabled(canCopy);
+            moveTo.setEnabled(canCopy && canDelete);
             rename.setEnabled(canRename);
 
             menu.findItem(R.id.menu_share).setVisible(true);
             menu.findItem(R.id.menu_delete).setVisible(canDelete);
             menu.findItem(R.id.menu_open).setVisible(false);
-            menu.findItem(R.id.menu_copy_to).setVisible(true);
-            menu.findItem(R.id.menu_move_to).setVisible(true);
-            menu.findItem(R.id.menu_move_to).setEnabled(canDelete);
 
             Menus.disableHiddenItems(menu, copy, paste);
         }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
index ab4f5c4..c5ee592 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
@@ -153,48 +153,53 @@
     private void updateModelData() {
         int[] positions = new int[mCursorCount];
         mIds = new String[mCursorCount];
-        String[] stringValues = new String[mCursorCount];
+        boolean[] isDirs = new boolean[mCursorCount];
+        String[] displayNames = null;
         long[] longValues = null;
 
-        if (mSortOrder == SORT_ORDER_LAST_MODIFIED || mSortOrder == SORT_ORDER_SIZE) {
-            longValues = new long[mCursorCount];
+        switch (mSortOrder) {
+            case SORT_ORDER_DISPLAY_NAME:
+                displayNames = new String[mCursorCount];
+                break;
+            case SORT_ORDER_LAST_MODIFIED:
+            case SORT_ORDER_SIZE:
+                longValues = new long[mCursorCount];
+                break;
         }
 
+        String mimeType;
+
         mCursor.moveToPosition(-1);
         for (int pos = 0; pos < mCursorCount; ++pos) {
             mCursor.moveToNext();
             positions[pos] = pos;
             mIds[pos] = createModelId(mCursor);
 
+            mimeType = getCursorString(mCursor, Document.COLUMN_MIME_TYPE);
+            isDirs[pos] = Document.MIME_TYPE_DIR.equals(mimeType);
+
             switch(mSortOrder) {
                 case SORT_ORDER_DISPLAY_NAME:
-                    final String mimeType = getCursorString(mCursor, Document.COLUMN_MIME_TYPE);
                     final String displayName = getCursorString(
                             mCursor, Document.COLUMN_DISPLAY_NAME);
-                    if (Document.MIME_TYPE_DIR.equals(mimeType)) {
-                        stringValues[pos] = Shared.DIR_PREFIX + displayName;
-                    } else {
-                        stringValues[pos] = displayName;
-                    }
+                    displayNames[pos] = displayName;
                     break;
                 case SORT_ORDER_LAST_MODIFIED:
                     longValues[pos] = getLastModified(mCursor);
-                    stringValues[pos] = getCursorString(mCursor, Document.COLUMN_MIME_TYPE);
                     break;
                 case SORT_ORDER_SIZE:
                     longValues[pos] = getCursorLong(mCursor, Document.COLUMN_SIZE);
-                    stringValues[pos] = getCursorString(mCursor, Document.COLUMN_MIME_TYPE);
                     break;
             }
         }
 
         switch (mSortOrder) {
             case SORT_ORDER_DISPLAY_NAME:
-                binarySort(stringValues, positions, mIds);
+                binarySort(displayNames, isDirs, positions, mIds);
                 break;
             case SORT_ORDER_LAST_MODIFIED:
             case SORT_ORDER_SIZE:
-                binarySort(longValues, stringValues, positions, mIds);
+                binarySort(longValues, isDirs, positions, mIds);
                 break;
         }
 
@@ -207,18 +212,20 @@
 
     /**
      * Sorts model data. Takes three columns of index-corresponded data. The first column is the
-     * sort key. Rows are sorted in ascending alphabetical order on the sort key. This code is based
-     * on TimSort.binarySort().
+     * sort key. Rows are sorted in ascending alphabetical order on the sort key.
+     * Directories are always shown first. This code is based on TimSort.binarySort().
      *
      * @param sortKey Data is sorted in ascending alphabetical order.
+     * @param isDirs Array saying whether an item is a directory or not.
      * @param positions Cursor positions to be sorted.
      * @param ids Model IDs to be sorted.
      */
-    private static void binarySort(String[] sortKey, int[] positions, String[] ids) {
+    private static void binarySort(String[] sortKey, boolean[] isDirs, int[] positions, String[] ids) {
         final int count = positions.length;
         for (int start = 1; start < count; start++) {
             final int pivotPosition = positions[start];
             final String pivotValue = sortKey[start];
+            final boolean pivotIsDir = isDirs[start];
             final String pivotId = ids[start];
 
             int left = 0;
@@ -227,9 +234,18 @@
             while (left < right) {
                 int mid = (left + right) >>> 1;
 
-                final String lhs = pivotValue;
-                final String rhs = sortKey[mid];
-                final int compare = Shared.compareToIgnoreCaseNullable(lhs, rhs);
+                // Directories always go in front.
+                int compare = 0;
+                final boolean rhsIsDir = isDirs[mid];
+                if (pivotIsDir && !rhsIsDir) {
+                    compare = -1;
+                } else if (!pivotIsDir && rhsIsDir) {
+                    compare = 1;
+                } else {
+                    final String lhs = pivotValue;
+                    final String rhs = sortKey[mid];
+                    compare = Shared.compareToIgnoreCaseNullable(lhs, rhs);
+                }
 
                 if (compare < 0) {
                     right = mid;
@@ -243,20 +259,24 @@
                 case 2:
                     positions[left + 2] = positions[left + 1];
                     sortKey[left + 2] = sortKey[left + 1];
+                    isDirs[left + 2] = isDirs[left + 1];
                     ids[left + 2] = ids[left + 1];
                 case 1:
                     positions[left + 1] = positions[left];
                     sortKey[left + 1] = sortKey[left];
+                    isDirs[left + 1] = isDirs[left];
                     ids[left + 1] = ids[left];
                     break;
                 default:
                     System.arraycopy(positions, left, positions, left + 1, n);
                     System.arraycopy(sortKey, left, sortKey, left + 1, n);
+                    System.arraycopy(isDirs, left, isDirs, left + 1, n);
                     System.arraycopy(ids, left, ids, left + 1, n);
             }
 
             positions[left] = pivotPosition;
             sortKey[left] = pivotValue;
+            isDirs[left] = pivotIsDir;
             ids[left] = pivotId;
         }
     }
@@ -268,17 +288,17 @@
      * numerical order on the sort key. This code is based on TimSort.binarySort().
      *
      * @param sortKey Data is sorted in descending numerical order.
-     * @param mimeTypes Corresponding mime types. Directories will be sorted ahead of documents.
+     * @param isDirs Array saying whether an item is a directory or not.
      * @param positions Cursor positions to be sorted.
      * @param ids Model IDs to be sorted.
      */
     private static void binarySort(
-            long[] sortKey, String[] mimeTypes, int[] positions, String[] ids) {
+            long[] sortKey, boolean[] isDirs, int[] positions, String[] ids) {
         final int count = positions.length;
         for (int start = 1; start < count; start++) {
             final int pivotPosition = positions[start];
             final long pivotValue = sortKey[start];
-            final String pivotMime = mimeTypes[start];
+            final boolean pivotIsDir = isDirs[start];
             final String pivotId = ids[start];
 
             int left = 0;
@@ -287,13 +307,12 @@
             while (left < right) {
                 int mid = ((left + right) >>> 1);
 
-                // First bucket by mime type.  Directories always go in front.
+                // Directories always go in front.
                 int compare = 0;
-                final boolean lhsIsDir = Document.MIME_TYPE_DIR.equals(pivotMime);
-                final boolean rhsIsDir = Document.MIME_TYPE_DIR.equals(mimeTypes[mid]);
-                if (lhsIsDir && !rhsIsDir) {
+                final boolean rhsIsDir = isDirs[mid];
+                if (pivotIsDir && !rhsIsDir) {
                     compare = -1;
-                } else if (!lhsIsDir && rhsIsDir) {
+                } else if (!pivotIsDir && rhsIsDir) {
                     compare = 1;
                 } else {
                     final long lhs = pivotValue;
@@ -323,24 +342,24 @@
                 case 2:
                     positions[left + 2] = positions[left + 1];
                     sortKey[left + 2] = sortKey[left + 1];
-                    mimeTypes[left + 2] = mimeTypes[left + 1];
+                    isDirs[left + 2] = isDirs[left + 1];
                     ids[left + 2] = ids[left + 1];
                 case 1:
                     positions[left + 1] = positions[left];
                     sortKey[left + 1] = sortKey[left];
-                    mimeTypes[left + 1] = mimeTypes[left];
+                    isDirs[left + 1] = isDirs[left];
                     ids[left + 1] = ids[left];
                     break;
                 default:
                     System.arraycopy(positions, left, positions, left + 1, n);
                     System.arraycopy(sortKey, left, sortKey, left + 1, n);
-                    System.arraycopy(mimeTypes, left, mimeTypes, left + 1, n);
+                    System.arraycopy(isDirs, left, isDirs, left + 1, n);
                     System.arraycopy(ids, left, ids, left + 1, n);
             }
 
             positions[left] = pivotPosition;
             sortKey[left] = pivotValue;
-            mimeTypes[left] = pivotMime;
+            isDirs[left] = pivotIsDir;
             ids[left] = pivotId;
         }
     }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
index d5327f9..31ce837 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
@@ -74,7 +74,6 @@
         summary = null;
         size = -1;
         icon = 0;
-
         derivedUri = null;
     }
 
@@ -210,6 +209,7 @@
                 + ", isContainer=" + isContainer()
                 + ", isDirectory=" + isDirectory()
                 + ", isArchive=" + isArchive()
+                + ", isPartial=" + isPartial()
                 + ", isVirtualDocument=" + isVirtualDocument()
                 + ", isDeleteSupported=" + isDeleteSupported()
                 + ", isCreateSupported=" + isCreateSupported()
@@ -249,6 +249,10 @@
         return (flags & Document.FLAG_ARCHIVE) != 0;
     }
 
+    public boolean isPartial() {
+        return (flags & Document.FLAG_PARTIAL) != 0;
+    }
+
     public boolean isContainer() {
         return isDirectory() || isArchive();
     }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
index 3eaf10a..3960475 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
@@ -55,7 +55,7 @@
     private static final int VERSION_DROP_TYPE = 2;
 
     // The values of these constants determine the sort order of various roots in the RootsFragment.
-    @IntDef(flag = true, value = {
+    @IntDef(flag = false, value = {
             TYPE_IMAGES,
             TYPE_VIDEO,
             TYPE_AUDIO,
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java
index 59dc232..e4afc3d 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java
@@ -183,6 +183,7 @@
 
     // We don't really need to test the entirety of download support
     // since downloads is (almost) just another provider.
+    @Suppress
     public void testDownload_Queued() throws Exception {
         DownloadManager dm = (DownloadManager) context.getSystemService(
                 Context.DOWNLOAD_SERVICE);
@@ -194,6 +195,7 @@
         bots.directory.assertDocumentsPresent("Queued");
     }
 
+    @Suppress
     public void testDownload_RetryUnsuccessful() throws Exception {
         DownloadManager dm = (DownloadManager) context.getSystemService(
                 Context.DOWNLOAD_SERVICE);
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
index 72ad2f6..8c73211 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
@@ -830,11 +830,21 @@
         if (info.getFormat() == MtpConstants.FORMAT_ASSOCIATION) {
             return DocumentsContract.Document.MIME_TYPE_DIR;
         }
+
         final String formatCodeMimeType = MediaFile.getMimeTypeForFormatCode(info.getFormat());
+        final String mediaFileMimeType = MediaFile.getMimeTypeForFile(info.getName());
+
+        // Format code can be mapped with multiple mime types, e.g. FORMAT_MPEG is mapped with
+        // audio/mp4 and video/mp4.
+        // As file extension contains more information than format code, returns mime type obtained
+        // from file extension if it is consistent with format code.
+        if (mediaFileMimeType != null &&
+                MediaFile.getFormatCode("", mediaFileMimeType) == info.getFormat()) {
+            return mediaFileMimeType;
+        }
         if (formatCodeMimeType != null) {
             return formatCodeMimeType;
         }
-        final String mediaFileMimeType = MediaFile.getMimeTypeForFile(info.getName());
         if (mediaFileMimeType != null) {
             return mediaFileMimeType;
         }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index d4d4591..58ff401 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -36,7 +36,6 @@
 import android.provider.DocumentsContract;
 import android.provider.DocumentsProvider;
 import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
@@ -48,6 +47,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.TimeoutException;
 
 /**
  * DocumentsProvider for MTP devices.
@@ -426,7 +426,7 @@
                     closeDeviceInternal(id);
                 }
                 mRootScanner.pause();
-            } catch (InterruptedException|IOException e) {
+            } catch (InterruptedException | IOException | TimeoutException e) {
                 // It should fail unit tests by throwing runtime exception.
                 throw new RuntimeException(e);
             } finally {
@@ -464,9 +464,6 @@
         getDeviceToolkit(deviceId).close();
         mDeviceToolkits.remove(deviceId);
         mMtpManager.closeDevice(deviceId);
-        if (mDeviceToolkits.size() == 0) {
-            mRootScanner.pause();
-        }
     }
 
     private DeviceToolkit getDeviceToolkit(int deviceId) throws FileNotFoundException {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java b/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java
index 2f66c5c..2e9133b 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java
@@ -27,6 +27,7 @@
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 final class RootScanner {
     /**
@@ -95,15 +96,19 @@
      * Stops background thread and wait for its termination.
      * @throws InterruptedException
      */
-    synchronized void pause() throws InterruptedException {
+    synchronized void pause() throws InterruptedException, TimeoutException {
         if (mExecutor == null) {
             return;
         }
         mExecutor.shutdownNow();
-        if (!mExecutor.awaitTermination(AWAIT_TERMINATION_TIMEOUT, TimeUnit.MILLISECONDS)) {
-            Log.e(MtpDocumentsProvider.TAG, "Failed to terminate RootScanner's background thread.");
+        try {
+            if (!mExecutor.awaitTermination(AWAIT_TERMINATION_TIMEOUT, TimeUnit.MILLISECONDS)) {
+                throw new TimeoutException(
+                        "Timeout for terminating RootScanner's background thread.");
+            }
+        } finally {
+            mExecutor = null;
         }
-        mExecutor = null;
     }
 
     /**
@@ -173,6 +178,9 @@
                 }
                 mFirstScanCompleted.countDown();
                 pollingCount++;
+                if (devices.length == 0) {
+                    break;
+                }
                 try {
                     // Use SHORT_POLLING_PERIOD for the first SHORT_POLLING_TIMES because it is
                     // more likely to add new root just after the device is added.
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
index e49a935..b74069a 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
@@ -17,6 +17,8 @@
 package com.android.mtp;
 
 import android.database.Cursor;
+import android.media.MediaFile;
+import android.media.MediaFile.MediaFileType;
 import android.mtp.MtpConstants;
 import android.mtp.MtpObjectInfo;
 import android.net.Uri;
@@ -1081,6 +1083,43 @@
         }
     }
 
+    public void testFormatCodeForMpeg() throws FileNotFoundException {
+        addTestDevice();
+        addTestStorage("1");
+        mDatabase.getMapper().startAddingDocuments("2");
+        mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
+            createDocument(100, "audio.m4a", MtpConstants.FORMAT_MPEG, 1000),
+            createDocument(101, "video.m4v", MtpConstants.FORMAT_MPEG, 1000),
+            createDocument(102, "unknown.mp4", MtpConstants.FORMAT_MPEG, 1000),
+            createDocument(103, "inconsistent.txt", MtpConstants.FORMAT_MPEG, 1000),
+            createDocument(104, "noext", MtpConstants.FORMAT_UNDEFINED, 1000),
+        });
+        mDatabase.getMapper().stopAddingDocuments("2");
+        try (final Cursor cursor = mDatabase.queryChildDocuments(
+                strings(COLUMN_DISPLAY_NAME,  COLUMN_MIME_TYPE),
+                "2")) {
+            assertEquals(5, cursor.getCount());
+            cursor.moveToNext();
+            assertEquals("audio.m4a", cursor.getString(0));
+            assertEquals("audio/mp4", cursor.getString(1));
+            cursor.moveToNext();
+            assertEquals("video.m4v", cursor.getString(0));
+            assertEquals("video/mp4", cursor.getString(1));
+            cursor.moveToNext();
+            // Assume that the file is video as we don't have any hints to find out if the file is
+            // video or audio.
+            assertEquals("unknown.mp4", cursor.getString(0));
+            assertEquals("video/mp4", cursor.getString(1));
+            // Don't return mime type that is inconsistent with format code.
+            cursor.moveToNext();
+            assertEquals("inconsistent.txt", cursor.getString(0));
+            assertEquals("video/mp4", cursor.getString(1));
+            cursor.moveToNext();
+            assertEquals("noext", cursor.getString(0));
+            assertEquals("application/octet-stream", cursor.getString(1));
+        }
+    }
+
     private void addTestDevice() throws FileNotFoundException {
         TestUtil.addTestDevice(mDatabase);
     }
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
index d6ad0f3..afcb457 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
@@ -262,11 +262,9 @@
                 null));
         {
             mProvider.openDevice(0);
-            mProvider.resumeRootScanner();
             mResolver.waitForNotification(ROOTS_URI, 1);
 
             mProvider.openDevice(1);
-            mProvider.resumeRootScanner();
             mResolver.waitForNotification(ROOTS_URI, 2);
 
             final Cursor cursor = mProvider.queryRoots(null);
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
index cdddd81..a08d9ee 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
@@ -48,6 +48,7 @@
     @Override
     protected void tearDown() throws Exception {
         assertTrue(mPipeManager.close());
+        mDatabase.close();
     }
 
     public void testReadDocument_basic() throws Exception {
diff --git a/packages/PrintSpooler/res/values-es/strings.xml b/packages/PrintSpooler/res/values-es/strings.xml
index a0ce57a..dba0491 100644
--- a/packages/PrintSpooler/res/values-es/strings.xml
+++ b/packages/PrintSpooler/res/values-es/strings.xml
@@ -66,8 +66,8 @@
     <string name="print_no_print_services" msgid="8561247706423327966">"No hay servicios de impresión habilitados"</string>
     <string name="print_no_printers" msgid="4869403323900054866">"No se encontraron impresoras"</string>
     <string name="cannot_add_printer" msgid="7840348733668023106">"No se pueden añadir impresoras"</string>
-    <string name="select_to_add_printers" msgid="3800709038689830974">"Seleccionar para añadir una impresora"</string>
-    <string name="enable_print_service" msgid="3482815747043533842">"Seleccionar para habilitar"</string>
+    <string name="select_to_add_printers" msgid="3800709038689830974">"Selecciona para añadir una impresora"</string>
+    <string name="enable_print_service" msgid="3482815747043533842">"Selecciona para habilitar"</string>
     <string name="enabled_services_title" msgid="7036986099096582296">"Servicios habilitados"</string>
     <string name="recommended_services_title" msgid="3799434882937956924">"Servicios recomendados"</string>
     <string name="disabled_services_title" msgid="7313253167968363211">"Servicios inhabilitados"</string>
diff --git a/packages/PrintSpooler/res/values-ne-rNP/strings.xml b/packages/PrintSpooler/res/values-ne-rNP/strings.xml
index e12c8df..5af3a04 100644
--- a/packages/PrintSpooler/res/values-ne-rNP/strings.xml
+++ b/packages/PrintSpooler/res/values-ne-rNP/strings.xml
@@ -68,7 +68,7 @@
     <string name="cannot_add_printer" msgid="7840348733668023106">"प्रिन्टरहरू थप्न सक्दैन"</string>
     <string name="select_to_add_printers" msgid="3800709038689830974">"प्रिन्टर थप्नका लागि चयन गर्नुहोस्"</string>
     <string name="enable_print_service" msgid="3482815747043533842">"सक्षम गर्नका लागि चयन गर्नुहोस्"</string>
-    <string name="enabled_services_title" msgid="7036986099096582296">"सेवाहरूलाई सक्षम गर्नुहोस्"</string>
+    <string name="enabled_services_title" msgid="7036986099096582296">"सक्षम गरिएका सेवाहरू"</string>
     <string name="recommended_services_title" msgid="3799434882937956924">"सिफारिस गरिएका सेवाहरू"</string>
     <string name="disabled_services_title" msgid="7313253167968363211">"असक्षम गरिएका सेवाहरू"</string>
     <string name="all_services_title" msgid="5578662754874906455">"सबै सेवाहरू"</string>
diff --git a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
index ee6266f..a6af5bd 100644
--- a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
+++ b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
@@ -61,7 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Printer haqida batafsil ma’lumot"</string>
-    <string name="print_services_disabled_toast" msgid="9089060734685174685">"Bir qancha chop etish xizmatlari o‘chirilgan"</string>
+    <string name="print_services_disabled_toast" msgid="9089060734685174685">"Ayrim chop etish xizmatlari o‘chirib qo‘yilgan"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Printerlar qidirilmoqda"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Hech qaysi chop etish xizmati yoqilmagan"</string>
     <string name="print_no_printers" msgid="4869403323900054866">"Printerlar topilmadi"</string>
@@ -70,7 +70,7 @@
     <string name="enable_print_service" msgid="3482815747043533842">"Yoqish uchun tanlang"</string>
     <string name="enabled_services_title" msgid="7036986099096582296">"Yoqilgan xizmatlar"</string>
     <string name="recommended_services_title" msgid="3799434882937956924">"Tavsiya etilgan xizmatlar"</string>
-    <string name="disabled_services_title" msgid="7313253167968363211">"O‘chirilgan xizmatlar"</string>
+    <string name="disabled_services_title" msgid="7313253167968363211">"O‘chirib qo‘yilgan xizmatlar"</string>
     <string name="all_services_title" msgid="5578662754874906455">"Barcha xizmatlar"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Chop etilmoqda: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> bekor qilinmoqda"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
index 47023c1..d0aba22 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
@@ -146,12 +146,13 @@
     public boolean setDisabledByAdmin(EnforcedAdmin admin) {
         final boolean disabled = (admin != null ? true : false);
         mEnforcedAdmin = admin;
-        mPreference.setEnabled(!disabled);
+        boolean changed = false;
         if (mDisabledByAdmin != disabled) {
             mDisabledByAdmin = disabled;
-            return true;
+            changed = true;
         }
-        return false;
+        mPreference.setEnabled(!disabled);
+        return changed;
     }
 
     public boolean isDisabledByAdmin() {
diff --git a/packages/Shell/res/values-am/strings.xml b/packages/Shell/res/values-am/strings.xml
index fae820c..b0d3de0 100644
--- a/packages/Shell/res/values-am/strings.xml
+++ b/packages/Shell/res/values-am/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"ቀፎ"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"የሳንካ ሪፖርት <xliff:g id="ID">#%d</xliff:g> እየተመነጨ ነው"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"የሳንካ ሪፖርት <xliff:g id="ID">#%d</xliff:g> ተወስዷል"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"የሳንካ ሪፖርት <xliff:g id="ID">#%d</xliff:g> ፎቶ ተነስቷል፣ ነገር ግን ቅጽበታዊ ገጽ ማያ በመጠባበቅ ላይ ነው"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"ዝርዝሮችን ወደ የሳንካ ሪፖርቱ በማከል ላይ"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"እባክዎ ይጠብቁ…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"የሳንካ ሪፖርትዎን ለማጋራት ወደ ግራ ያንሸራትቱ"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"የሳንካ ሪፖርትዎን ለማጋራት መታ ያድርጉ"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"የእርስዎን የሳንካ ሪፖርት ያለ ቅጽበታዊ ማያ ገጽ ለማጋራት መታ ያድርጉ ወይም ቅጽበታዊ ማያ ገጹ እስኪጨርስ ይጠብቁ"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"የእርስዎን የሳንካ ሪፖርት ያለ ቅጽበታዊ ማያ ገጽ ለማጋራት መታ ያድርጉ ወይም ቅጽበታዊ ማያ ገጹ እስኪጨርስ ይጠብቁ"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"የሳንካ ሪፖርቶች የግል መረጃን ጨምሮ ከበርካታ የስርዓቱ ምዝግብ ማስታወሻዎች የመጣ ውሂብን ይዟል። የሳንካ ሪፖርቶች ለሚያምኗቸው መተግበሪያዎችን እና ሰዎችን ብቻ ያጋሩ።"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ይህን መልዕክት በሚቀጥለው ጊዜ አሳይ"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"የሳንካ ሪፖርቶች"</string>
diff --git a/packages/Shell/res/values-az-rAZ/strings.xml b/packages/Shell/res/values-az-rAZ/strings.xml
index 6172e7d..22791a6 100644
--- a/packages/Shell/res/values-az-rAZ/strings.xml
+++ b/packages/Shell/res/values-az-rAZ/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Baq hesabatı <xliff:g id="ID">#%d</xliff:g> yaradıldı"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Baq hesabatı <xliff:g id="ID">#%d</xliff:g> alındı"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"<xliff:g id="ID">#%d</xliff:g> baq hesabatı çəkildi, amma skrinşot hələ gözlənilir"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Detallar baq hesabatına əlavə olunur"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Lütfən, gözləyin..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Baq raportunu paylaşmaq üçün sola sürüşdürün"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Baq hesabatınızı paylaşmaq üçün tıklayın"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"baq hesabatınızı skrinşot olmadan paylaşmaq üçün tıklayın, skrinşotun tamamlanması üçün isə gözləyin"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"baq hesabatınızı skrinşot olmadan paylaşmaq üçün tıklayın, skrinşotun tamamlanması üçün isə gözləyin"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Baq raportları sistemin müxtəlif jurnal fayllarından data içərir ki, buna şəxsi və konfidensial məlumatlar da aiddir. Yalnız inandığınız adamlarla baq raportlarını paylaşın."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Bu mesajı növbəti dəfə göstər"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Baq hesabatları"</string>
diff --git a/packages/Shell/res/values-bg/strings.xml b/packages/Shell/res/values-bg/strings.xml
index 6a69f7d..0f8676f 100644
--- a/packages/Shell/res/values-bg/strings.xml
+++ b/packages/Shell/res/values-bg/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Команден ред"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Сигналът за програмна грешка „<xliff:g id="ID">#%d</xliff:g>“ се генерира"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Сигналът за програмна грешка „<xliff:g id="ID">#%d</xliff:g>“ е заснет"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Сигналът (<xliff:g id="ID">#%d</xliff:g>) е заснет, но екр. снимка не е готова"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Подробностите се добавят към сигнала за пр. грешка"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Моля, изчакайте…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Прекарайте пръст наляво, за да споделите сигнала си за програмна грешка"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Докоснете, за да споделите сигнала си за програмна грешка"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Докоснете, за да споделите сигнала за прогр. грешка без екранна снимка, или изчакайте завършването й"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Докоснете, за да споделите сигнала за прогр. грешка без екранна снимка, или изчакайте завършването й"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Отчетите за програмни грешки съдържат данни от различни регистрационни файлове на системата, включително лична и поверителна информация. Споделяйте ги само с приложения и хора, на които имате доверие."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Това съобщение да се показва следващия път"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Отчети за прогр. грешки"</string>
diff --git a/packages/Shell/res/values-bs-rBA/strings.xml b/packages/Shell/res/values-bs-rBA/strings.xml
index a38be0e..f4d71e9 100644
--- a/packages/Shell/res/values-bs-rBA/strings.xml
+++ b/packages/Shell/res/values-bs-rBA/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Ljuska"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Izvještaj o grešci <xliff:g id="ID">#%d</xliff:g> se generira"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Izvještaj o grešci <xliff:g id="ID">#%d</xliff:g> je snimljen"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Izvještaj o greškama <xliff:g id="ID">#%d</xliff:g> snimljen, čeka se snim. ekr."</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodavanje detalja u izvještaj o greškama"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Pričekajte..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Prevucite lijevo da podijelite izvještaj o greškama"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dodirnite da biste podijelili izvještaj o grešci"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Dodirnite da podijelite izveštaj o greškama bez snimka ekrana ili sačekajte da snimak bude gotov"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Dodirnite da podijelite izveštaj o greškama bez snimka ekrana ili sačekajte da snimak bude gotov"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Izvještaji o greškama sadrže podatke iz raznih zapisnika sistema, uključujući lične i privatne informacije. Podijelite izvještaje o greškama samo sa aplikacijama i osobama kojima vjerujete."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Pokaži ovu poruku sljedeći put"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Izvještaji o greškama"</string>
diff --git a/packages/Shell/res/values-ca/strings.xml b/packages/Shell/res/values-ca/strings.xml
index c246ec4..3efb53b 100644
--- a/packages/Shell/res/values-ca/strings.xml
+++ b/packages/Shell/res/values-ca/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Protecció"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"S\'està generant l\'informe d\'errors <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"S\'ha capturat l\'informe d\'errors <xliff:g id="ID">#%d</xliff:g>"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"L\'informe d\'errors <xliff:g id="ID">#%d</xliff:g> s\'ha capturat (captura pendent)"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"S\'estan afegint detalls a l\'informe d\'errors"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Espera…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Llisca cap a l\'esquerra per compartir l\'informe d\'errors."</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toca per compartir l\'informe d\'errors"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Toca per compartir l\'informe d\'errors sense captura de pantalla o espera que es creï la captura"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Toca per compartir l\'informe d\'errors sense captura de pantalla o espera que es creï la captura"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Els informes d\'error contenen dades dels diferents fitxers de registre del sistema, inclosa informació privada i personal. Comparteix els informes d\'error només amb les aplicacions i amb les persones en qui confies."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostra aquest missatge la propera vegada"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Informes d\'error"</string>
diff --git a/packages/Shell/res/values-cs/strings.xml b/packages/Shell/res/values-cs/strings.xml
index ebd9b53..afb6f9e 100644
--- a/packages/Shell/res/values-cs/strings.xml
+++ b/packages/Shell/res/values-cs/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Zpráva o chybě <xliff:g id="ID">#%d</xliff:g> se vytváří"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Zpráva o chybě <xliff:g id="ID">#%d</xliff:g> byla vytvořena"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Zpráva o chybě <xliff:g id="ID">#%d</xliff:g> byla vytvořena, čeká se na snímek"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Přidávání podrobností do zprávy o chybě"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Čekejte prosím…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Chcete-li hlášení chyby sdílet, přejeďte doleva."</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Zprávu o chybě můžete sdílet klepnutím"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Klepnutím můžete zprávu o chybě sdílet bez snímku obrazovky, nebo vyčkejte, než se snímek připraví"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Klepnutím můžete zprávu o chybě sdílet bez snímku obrazovky, nebo vyčkejte, než se snímek připraví"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Chybová hlášení obsahují data z různých souborů protokolů systému včetně osobních a soukromých informací. Chybová hlášení sdílejte pouze s aplikacemi a uživateli, kterým důvěřujete."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Zobrazit tuto zprávu příště"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Zprávy o chybách"</string>
diff --git a/packages/Shell/res/values-es-rUS/strings.xml b/packages/Shell/res/values-es-rUS/strings.xml
index 3f7f4d6..307548a 100644
--- a/packages/Shell/res/values-es-rUS/strings.xml
+++ b/packages/Shell/res/values-es-rUS/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Se está generando el informe de errores <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Se capturó el informe de errores <xliff:g id="ID">#%d</xliff:g>"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Informe de errores <xliff:g id="ID">#%d</xliff:g> capturado (captura pendiente)"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Agregando detalles al informe de errores"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Espera…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Desliza el dedo hacia la izquierda para compartir el informe de errores."</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toca para compartir el informe de errores"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Toca para compartir tu informe de errores sin una captura de pantalla o espera a que finalice"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Toca para compartir tu informe de errores sin una captura de pantalla o espera a que finalice"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Los informes de errores contienen datos de los distintos archivos de registro del sistema, incluida la información personal y privada. Comparte los informes de errores únicamente con aplicaciones y personas en las que confíes."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar este mensaje la próxima vez"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Informes de errores"</string>
diff --git a/packages/Shell/res/values-eu-rES/strings.xml b/packages/Shell/res/values-eu-rES/strings.xml
index 8f4d219..7946f67 100644
--- a/packages/Shell/res/values-eu-rES/strings.xml
+++ b/packages/Shell/res/values-eu-rES/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Shell-interfazea"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Akatsen <xliff:g id="ID">#%d</xliff:g> txostena egiten ari gara"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Akatsen <xliff:g id="ID">#%d</xliff:g> txostena egin da"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Egin da <xliff:g id="ID">#%d</xliff:g> txostena. Pantaila-argazkia falta da."</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Akatsen txostenean xehetasunak gehitzen"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Itxaron, mesedez…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Programa-akatsen txostena partekatzeko, pasatu hatza ezkerrera"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Sakatu akatsen txostena partekatzeko"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Sakatu akatsen txostena argazkirik gabe partekatzeko edo itxaron pantaila-argazkia atera arte"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Sakatu akatsen txostena argazkirik gabe partekatzeko edo itxaron pantaila-argazkia atera arte"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Akatsen txostenek sistemaren erregistro-fitxategietako datuak dauzkate, informazio pertsonala eta pribatua barne. Akatsen txostenak partekatzen badituzu, partekatu soilik aplikazio eta pertsona fidagarriekin."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Erakutsi mezu hau hurrengoan"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Akatsen txostenak"</string>
diff --git a/packages/Shell/res/values-fa/strings.xml b/packages/Shell/res/values-fa/strings.xml
index c0f4d2a..ecadf1a 100644
--- a/packages/Shell/res/values-fa/strings.xml
+++ b/packages/Shell/res/values-fa/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"گزارش اشکال <xliff:g id="ID">#%d</xliff:g> در حال ایجاد شدن است"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"گزارش اشکال <xliff:g id="ID">#%d</xliff:g> ثبت شد"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"گزارش اشکال <xliff:g id="ID">#%d</xliff:g> گرفته شد اما عکس از صفحه‌نمایش هنوز نه"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"اضافه کردن جزئیات به گزارش اشکال"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"لطفاً منتظر بمانید..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"برای اشتراک‌گذاری گزارش اشکال، به تندی آن را به چپ بکشید"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"برای به اشتراک گذاشتن گزارش اشکال، ضربه بزنید"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"برای اشتراک‌گذاری گزارش مشکل بدون عکس صفحه‌نمایش، ضربه بزنید یا صبر کنید تا عکس صفحه‌نمایش گرفته شود."</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"برای اشتراک‌گذاری گزارش مشکل بدون عکس صفحه‌نمایش، ضربه بزنید یا صبر کنید تا عکس صفحه‌نمایش گرفته شود."</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"گزارش‌های اشکال حاوی داده‌هایی از فایل‌های گزارش مختلف در سیستم هستند، شامل اطلاعات شخصی و خصوصی. گزارش‌های اشکال را فقط با افراد و برنامه‌های مورد اعتماد خود به اشتراک بگذارید."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"دفعه بعد این پیام نشان داده شود"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"گزارش اشکال"</string>
diff --git a/packages/Shell/res/values-fi/strings.xml b/packages/Shell/res/values-fi/strings.xml
index 64245aa..b5ae006 100644
--- a/packages/Shell/res/values-fi/strings.xml
+++ b/packages/Shell/res/values-fi/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Komentotulkki"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Luodaan virheraporttia <xliff:g id="ID">#%d</xliff:g>."</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Virheraportti <xliff:g id="ID">#%d</xliff:g> tallennettu"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Virheraportti <xliff:g id="ID">#%d</xliff:g> tallennettu, kuvakaappaus odottaa."</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Lisätään tietoja virheraporttiin"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Odota…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Jaa virheraportti pyyhkäisemällä vasemmalle"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Jaa virheraportti napauttamalla."</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Jaa virheraportti ilman kuvakaappausta napauttamalla tai odota, että kuvakaappaus latautuu."</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Jaa virheraportti ilman kuvakaappausta napauttamalla tai odota, että kuvakaappaus latautuu."</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Virheraportit sisältävät järjestelmän lokitietoja, ja niihin voi sisältyä henkilökohtaisia ja yksityisiä tietoja. Jaa virheraportteja vain luotettaville sovelluksille ja käyttäjille."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Näytä tämä viesti seuraavalla kerralla"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Virheraportit"</string>
diff --git a/packages/Shell/res/values-fr-rCA/strings.xml b/packages/Shell/res/values-fr-rCA/strings.xml
index 9575273..6c40edd 100644
--- a/packages/Shell/res/values-fr-rCA/strings.xml
+++ b/packages/Shell/res/values-fr-rCA/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Rapport de bogue <xliff:g id="ID">#%d</xliff:g> généré"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Rapport de bogue <xliff:g id="ID">#%d</xliff:g> enregistré"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Rap. bogue <xliff:g id="ID">#%d</xliff:g> enreg., mais attente de saisie d\'écran"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Ajout de détails au rapport de bogue"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Veuillez patienter…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Faites glisser le doigt vers la gauche pour partager votre rapport de bogue."</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Touchez ici pour partager votre rapport de bogue"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Touchez pour partager le rapport de bogue sans saisie d\'écran ou attendez que la saisie soit prête"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Touchez pour partager le rapport de bogue sans saisie d\'écran ou attendez que la saisie soit prête"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Les rapports de bogue contiennent des données des fichiers journaux du système, y compris des informations personnelles et privées. Ne partagez les rapports de bogue qu\'avec les applications et les personnes que vous estimez fiables."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Afficher ce message la prochaine fois"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Rapports de bogues"</string>
diff --git a/packages/Shell/res/values-fr/strings.xml b/packages/Shell/res/values-fr/strings.xml
index 83d30e6..54f0b98 100644
--- a/packages/Shell/res/values-fr/strings.xml
+++ b/packages/Shell/res/values-fr/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Le rapport de bug \"<xliff:g id="ID">#%d</xliff:g>\" est en cours de création"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Le rapport de bug \"<xliff:g id="ID">#%d</xliff:g>\" a bien été enregistré"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Rapport bug \"<xliff:g id="ID">#%d</xliff:g>\" enregistré, mais attente capt. écran"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Ajout d\'informations au rapport de bug"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Veuillez patienter…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Faites glisser le doigt vers la gauche pour partager votre rapport d\'erreur."</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Appuyer pour partager votre rapport de bug"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Appuyer pour partager rapport de bug sans capture d\'écran ou attendre finalisation capture d\'écran"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Appuyer pour partager rapport de bug sans capture d\'écran ou attendre finalisation capture d\'écran"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Les rapports de bug contiennent des données des fichiers journaux du système, y compris des informations personnelles et privées. Ne partagez les rapports de bug qu\'avec les applications et les personnes que vous estimez fiables."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Afficher ce message la prochaine fois"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Rapports d\'erreur"</string>
diff --git a/packages/Shell/res/values-hy-rAM/strings.xml b/packages/Shell/res/values-hy-rAM/strings.xml
index 3cfe2f7..c9351c2 100644
--- a/packages/Shell/res/values-hy-rAM/strings.xml
+++ b/packages/Shell/res/values-hy-rAM/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Խեցի"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"<xliff:g id="ID">#%d</xliff:g> վրիպակի զեկույցը ստեղծվում է"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"<xliff:g id="ID">#%d</xliff:g> վրիպակի զեկույցը գրանցվեց"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"<xliff:g id="ID">#%d</xliff:g> վրիպակի զեկույցը ստեղծվել է, սակայն էկրանի պատկերը դեռ չի ստացվել"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Տվյալների ավելացում վրիպակի զեկույցում"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Խնդրում ենք սպասել…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Սահեցրեք ձախ՝ սխալի հաշվետվությունը համօգտագործելու համար"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Հպեք՝ վրիպակի զեկույցը տրամադրելու համար"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Հպեք՝ վրիպակի զեկույցն առանց էկրանի պատկերի ուղարկելու համար կամ սպասեք էկրանի պատկերի ստեղծմանը"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Հպեք՝ վրիպակի զեկույցն առանց էկրանի պատկերի ուղարկելու համար կամ սպասեք էկրանի պատկերի ստեղծմանը"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Վրիպակի զեկույցները պարունակում են տվյալներ համակարգի տարբեր մուտքի ֆայլերից, այդ թվում նաև անհատական ​​և գաղտնի տեղեկություններ: Վրիպակի զեկույցները կիսեք միայն այն հավելվածների և մարդկանց հետ, որոնց վստահում եք:"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Այս հաղորդագրությունը ցույց տալ հաջորդ անգամ"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Վրիպակների հաշվետվություններ"</string>
diff --git a/packages/Shell/res/values-ja/strings.xml b/packages/Shell/res/values-ja/strings.xml
index 33ddec9..a6ff33e 100644
--- a/packages/Shell/res/values-ja/strings.xml
+++ b/packages/Shell/res/values-ja/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"シェル"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"バグレポート <xliff:g id="ID">#%d</xliff:g> の生成中"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"バグレポート <xliff:g id="ID">#%d</xliff:g> の記録完了"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"バグレポート <xliff:g id="ID">#%d</xliff:g> 記録完了: スクリーンショット待ち"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"バグレポートに詳細情報を追加しています"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"お待ちください…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"バグレポートを共有するには左にスワイプ"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"バグレポートを共有するにはタップします"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"タップしてバグレポートをスクリーンショットなしで共有するか、スクリーンショット完成までお待ちください"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"タップしてバグレポートをスクリーンショットなしで共有するか、スクリーンショット完成までお待ちください"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"バグレポートには、個人の非公開情報など、システムのさまざまなログファイルのデータが含まれます。共有する場合は信頼するアプリとユーザーのみを選択してください。"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"このメッセージを次回も表示する"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"バグレポート"</string>
diff --git a/packages/Shell/res/values-ka-rGE/strings.xml b/packages/Shell/res/values-ka-rGE/strings.xml
index 61bdff7..119c360 100644
--- a/packages/Shell/res/values-ka-rGE/strings.xml
+++ b/packages/Shell/res/values-ka-rGE/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"გარეკანი"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ხარვეზების შესახებ ანგარიში <xliff:g id="ID">#%d</xliff:g> გენერირდება"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"ხარვეზების შესახებ ანგარიში <xliff:g id="ID">#%d</xliff:g> აღბეჭდილია"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"ხარვეზის ანგარიში <xliff:g id="ID">#%d</xliff:g> მზადაა. იქმნება ეკრანის ანაბეჭდი"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"ხარვეზის შესახებ ანგარიშს დეტალები ემატება"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"გთხოვთ, მოითმინოთ..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"გაასრიალეთ მარცხნივ თქვენი ხარვეზის შეტყობინების გასაზიარებლად"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"შეეხეთ ხარვეზების შესახებ ანგარიშის გასაზიარებლად"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"შეეხეთ ხარვეზის შესახებ ანგარიშის ეკრანის ანაბეჭდის გარეშე გასაზიარებლად, ან დაელოდეთ მის შექმნას"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"შეეხეთ ხარვეზის შესახებ ანგარიშის ეკრანის ანაბეჭდის გარეშე გასაზიარებლად, ან დაელოდეთ მის შექმნას"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"ხარვეზის ანგარიშები მოიცავს მონაცემებს სხვადასხვა სისტემური ჟურნალის ფაილებიდან, მათ შორის პირად და კონფიდენციალურ ინფორმაციას."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"შემდგომში აჩვენე ეს შეტყობინება"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"შეცდომების ანგარიშები"</string>
diff --git a/packages/Shell/res/values-kk-rKZ/strings.xml b/packages/Shell/res/values-kk-rKZ/strings.xml
index 403615a..9c2e4e7 100644
--- a/packages/Shell/res/values-kk-rKZ/strings.xml
+++ b/packages/Shell/res/values-kk-rKZ/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Қабыршық"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"<xliff:g id="ID">#%d</xliff:g> қате туралы есебі жасалуда"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"<xliff:g id="ID">#%d</xliff:g> қате туралы есебі жазып алынды"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"<xliff:g id="ID">#%d</xliff:g> қате туралы есебі жазып алынды, бірақ скриншот күтуде"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Қате туралы есепке мәліметтер қосылуда"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Күте тұрыңыз…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Қате туралы есепті бөлісу үшін солға жанаңыз"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Қате туралы есепті бөлісу үшін түртіңіз"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Қате туралы есепті скриншотсыз бөлісу үшін түртіңіз немесе скриншоттың аяқталуын күтіңіз"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Қате туралы есепті скриншотсыз бөлісу үшін түртіңіз немесе скриншоттың аяқталуын күтіңіз"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Вирус туралы баянатта жүйеде тіркелген әртүрлі файлдар туралы деректер болады, оған жеке және құпия ақпарат та кіреді. Вирус баянаттарын сенімді қолданбалар және сенімді адамдармен ғана бөлісіңіз."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Бұл хабарды келесі жолы көрсетіңіз"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Қате туралы баяндамалар"</string>
diff --git a/packages/Shell/res/values-km-rKH/strings.xml b/packages/Shell/res/values-km-rKH/strings.xml
index 05f5cc5..d5fc400 100644
--- a/packages/Shell/res/values-km-rKH/strings.xml
+++ b/packages/Shell/res/values-km-rKH/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"សែល"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"<xliff:g id="ID">#%d</xliff:g> របាយការណ៍កំហុសកំពុងត្រូវបានបង្កើត"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"<xliff:g id="ID">#%d</xliff:g> របាយការណ៍កំហុសត្រូវបានថត"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"<xliff:g id="ID">#%d</xliff:g> របាយការណ៍កំហុសត្រូវបានថត ប៉ុន្តែរូបថតអេក្រង់មិនទាន់បានថតនៅឡើយទេ"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"កំពុងបន្ថែមព័ត៌មានលម្អិតទៅរបាយការណ៍កំហុស"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"សូម​រង់ចាំ…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"អូស​ទៅ​ឆ្វេង​​ ដើម្បី​ចែក​រំលែក​របាយការណ៍​កំហុស​របស់​អ្នក"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"ប៉ះដើម្បីចែករំលែករបាយការណ៍កំហុសរបស់អ្នក"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"ប៉ះដើម្បីចែករំលែករបាយការណ៍កំហុសរបស់អ្នកដោយមិនចាំបាច់មានរូបថតអេក្រង់ ឬរង់ចាំការបញ្ចប់ការថតអេក្រង់"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"ប៉ះដើម្បីចែករំលែករបាយការណ៍កំហុសរបស់អ្នកដោយមិនចាំបាច់មានរូបថតអេក្រង់ ឬរង់ចាំការបញ្ចប់ការថតអេក្រង់"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"របាយការណ៍​កំហុស​រួមមាន​ឯកសារ​កំណត់​ហេតុ​ផ្សេងៗ​របស់​ប្រព័ន្ធ រួមមាន​ព័ត៌មាន​ផ្ទាល់ខ្លួន និង​ឯកជន។ ចែករំលែក​របាយការណ៍​កំហុស​ជា​មួយ​កម្មវិធី និង​មនុស្ស​ដែល​អ្នក​ទុក​ចិត្ត។"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"បង្ហាញ​សារ​នេះ​ពេល​ក្រោយ"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"រាយការណ៍ពីកំហុស"</string>
diff --git a/packages/Shell/res/values-ko/strings.xml b/packages/Shell/res/values-ko/strings.xml
index 8087304..4c0a169 100644
--- a/packages/Shell/res/values-ko/strings.xml
+++ b/packages/Shell/res/values-ko/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"셸"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"버그 신고 <xliff:g id="ID">#%d</xliff:g> 생성 중"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"버그 신고 <xliff:g id="ID">#%d</xliff:g> 캡처됨"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"버그 신고 <xliff:g id="ID">#%d</xliff:g>이(가) 캡처되었으나 스크린샷 대기 중"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"세부정보를 버그 보고서에 추가"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"잠시 기다려 주세요..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"왼쪽으로 스와이프하여 버그 신고서를 공유하세요."</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"버그 신고를 공유하려면 탭하세요."</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"스크린샷 없이 버그 신고서를 공유하려면 탭하고 그렇지 않으면 스크린샷이 완료될 때까지 기다려 주세요."</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"스크린샷 없이 버그 신고서를 공유하려면 탭하고 그렇지 않으면 스크린샷이 완료될 때까지 기다려 주세요."</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"버그 신고서는 시스템의 다양한 로그 파일 데이터(예: 개인 및 비공개 정보)를 포함합니다. 신뢰할 수 있는 앱과 사용자에게만 버그 신고서를 공유하세요."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"다음에 이 메시지 표시"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"버그 신고"</string>
diff --git a/packages/Shell/res/values-ky-rKG/strings.xml b/packages/Shell/res/values-ky-rKG/strings.xml
index cc5b2e5..e4039fe 100644
--- a/packages/Shell/res/values-ky-rKG/strings.xml
+++ b/packages/Shell/res/values-ky-rKG/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Командалык кабык"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Мүчүлүштүк тууралуу билдирүү <xliff:g id="ID">#%d</xliff:g> түзүлүүдө"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Мүчүлүштүк тууралуу билдирүү <xliff:g id="ID">#%d</xliff:g> жаздырылды"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Мүчүлүштүк тууралуу билдирүү <xliff:g id="ID">#%d</xliff:g> жаздырылды, бирок скриншот күтүлүүдө"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Мүчүлүштүк жөнүндө кабардын чоо-жайы кошулууда"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Күтө туруңуз…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Ката жөнүндө кабар менен бөлүшүү үчүн солго серпип коюңуз"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Мүчүлүштүк тууралуу билдирүүңүздү бөлүшүү үчүн таптап коюңуз"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Мүчүлүштүк тууралуу билдирүүңүздү скриншотсуз бөлүшүү үчүн таптап коюңуз же скриншот даяр болгуча күтө туруңуз"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Мүчүлүштүк тууралуу билдирүүңүздү скриншотсуз бөлүшүү үчүн таптап коюңуз же скриншот даяр болгуча күтө туруңуз"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Ката тууралуу билдирүүлөр системанын ар кандай лог файлдарынын берилиштерин камтыйт, аларга өздүк жана купуя маалыматтар дагы кирет. Ката тууралуу билдирүүлөрдү сиз ишенген колдонмолор жана адамдар менен гана бөлүшүңүз."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Бул билдирүү кийин көрсөтүлсүн"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Мүчүлүштүктөрдү кабарлоолор"</string>
diff --git a/packages/Shell/res/values-lo-rLA/strings.xml b/packages/Shell/res/values-lo-rLA/strings.xml
index 7685d44..2804528 100644
--- a/packages/Shell/res/values-lo-rLA/strings.xml
+++ b/packages/Shell/res/values-lo-rLA/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ກຳລັງສ້າງລາຍງານຂໍ້ຜິດພາດ <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"ບັນທຶກລາຍງານຂໍ້ຜິດພາດ <xliff:g id="ID">#%d</xliff:g> ແລ້ວ"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"ບັນທຶກລາຍງານຂໍ້ຜິດພາດ <xliff:g id="ID">#%d</xliff:g> ແລ້ວແຕ່ກຳລັງລໍຖ້າຮູບໜ້າຈໍຢູ່"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"ກຳລັງເພີ່ມລາຍລະອຽດໃສ່ລາຍງານຂໍ້ຜິດພາດ"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"ກະລຸນາລໍຖ້າ..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"​ປັດ​ໄປ​ຊ້າຍ​ເພື່ອ​ສົ່ງ​ລາຍ​ງານ​ຂໍ້​ຜິດ​ພາດ​ຂອງ​ທ່ານ"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"ແຕະເພື່ອແບ່ງປັນລາຍງານຂໍ້ຜິດພາດຂອງທ່ານ"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"ແຕະເພື່ອແບ່ງປັນລາຍງານຂໍ້ຜິດພາດຂອງທ່ານໂດຍບໍ່ໃຊ້ຮູບໜ້າຈໍ ຫຼື ລໍຖ້າໃຫ້ຮູບໜ້າຈໍແລ້ວໆ"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"ແຕະເພື່ອແບ່ງປັນລາຍງານຂໍ້ຜິດພາດຂອງທ່ານໂດຍບໍ່ໃຊ້ຮູບໜ້າຈໍ ຫຼື ລໍຖ້າໃຫ້ຮູບໜ້າຈໍແລ້ວໆ"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"ການລາຍງານຂໍ້ຜິດພາດປະກອບມີ ຂໍ້ມູນຈາກໄຟລ໌ບັນທຶກຂອງລະບົບຫຼາຍໄຟລ໌, ຮວມທັງຂໍ້ມູນສ່ວນໂຕນຳ. ທ່ານຕ້ອງແບ່ງປັນລາຍງານຂໍ້ຜິດພາດໃຫ້ແອັບຯ ແລະຄົນທີ່ທ່ານເຊື່ອຖືໄດ້ເທົ່ານັ້ນ."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ສະແດງຂໍ້ຄວາມນີ້ອີກໃນເທື່ອຕໍ່ໄປ"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"ລາຍ​ງານ​ບັນ​ຫາ"</string>
diff --git a/packages/Shell/res/values-lt/strings.xml b/packages/Shell/res/values-lt/strings.xml
index 202401a..a8468cf 100644
--- a/packages/Shell/res/values-lt/strings.xml
+++ b/packages/Shell/res/values-lt/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Apvalkalas"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Pranešimas apie riktą (<xliff:g id="ID">#%d</xliff:g>) generuojamas"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Pranešimas apie riktą (<xliff:g id="ID">#%d</xliff:g>) užfiksuotas"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Pranešimas apie riktą (<xliff:g id="ID">#%d</xliff:g>) užfiksuotas, bet laukiama ekrano kopijos"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Pridedama informacijos prie pranešimo apie riktą"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Palaukite…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Perbraukite kairėn, kad bendrintumėte rikto ataskaitą"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Palieskite, kad bendrintumėte pranešimą apie riktą"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Palieskite ir bendrinkite pranešimą apie riktą be ekrano kopijos arba palaukite, kol ji bus sukurta"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Palieskite ir bendrinkite pranešimą apie riktą be ekrano kopijos arba palaukite, kol ji bus sukurta"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Riktų ataskaitose pateikiami duomenys iš įvairių sistemos žurnalo failų, įskaitant asmeninę ir privačią informaciją. Riktų ataskaitas bendrinkite tik su patikimomis programomis ir žmonėmis."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Rodyti šį pranešimą kitą kartą"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Riktų ataskaitos"</string>
diff --git a/packages/Shell/res/values-lv/strings.xml b/packages/Shell/res/values-lv/strings.xml
index 93de35d..08e25be 100644
--- a/packages/Shell/res/values-lv/strings.xml
+++ b/packages/Shell/res/values-lv/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Aizsargs"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Kļūdas pārskats <xliff:g id="ID">#%d</xliff:g> tiek ģenerēts"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Kļūdas pārskats <xliff:g id="ID">#%d</xliff:g> reģistrēts"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Kļūdas pārskats <xliff:g id="ID">#%d</xliff:g> izveidots; gaida ekrānuzņēmumu"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Informācijas pievienošana kļūdas pārskatam"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Lūdzu, uzgaidiet..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Velciet pa kreisi, lai kopīgotu savu kļūdu ziņojumu."</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Pieskarieties, lai kopīgotu kļūdas pārskatu."</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Pieskarieties, lai kopīgotu kļūdas pārskatu bez ekrānuzņēmuma vai gaidiet ekrānuzņēmumu."</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Pieskarieties, lai kopīgotu kļūdas pārskatu bez ekrānuzņēmuma vai gaidiet ekrānuzņēmumu."</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Kļūdu pārskatā ir iekļauti dati no dažādiem sistēmas žurnālfailiem, tostarp personas dati un privāta informācija. Kļūdu pārskatus ieteicams kopīgot tikai ar uzticamām lietotnēm un lietotājiem."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Rādīt šo ziņojumu nākamajā reizē"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Kļūdu ziņojumi"</string>
diff --git a/packages/Shell/res/values-mk-rMK/strings.xml b/packages/Shell/res/values-mk-rMK/strings.xml
index f274f6d..3f879b7e 100644
--- a/packages/Shell/res/values-mk-rMK/strings.xml
+++ b/packages/Shell/res/values-mk-rMK/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Обвивка"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Се генерира извештајот за грешки <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Извештајот за грешки <xliff:g id="ID">#%d</xliff:g> е снимен"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Извештајот за грешка <xliff:g id="ID">#%d</xliff:g> е снимен. Се чека на сликата"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Се додаваат детали на извештајот за грешка"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Почекајте..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Повлечете налево за да споделите пријава за грешка"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Допрете за да го споделите извештајот за грешки"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Допрете за споделување извештај за грешки без слика од екранот или почекајте да се подготви сликата"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Допрете за споделување извештај за грешки без слика од екранот или почекајте да се подготви сликата"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Извештаите за грешка содржат податоци од разни датотеки за евиденција на системот, вклучувајќи лични и приватни информации. Извештаите за грешка споделувајте ги само со апликации и луѓе на коишто им верувате."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Прикажи ја поракава следниот пат"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Извештаи за грешки"</string>
diff --git a/packages/Shell/res/values-ml-rIN/strings.xml b/packages/Shell/res/values-ml-rIN/strings.xml
index d5d2e4e..3bb715d8 100644
--- a/packages/Shell/res/values-ml-rIN/strings.xml
+++ b/packages/Shell/res/values-ml-rIN/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"ഷെൽ"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ബഗ് റിപ്പോർട്ട് <xliff:g id="ID">#%d</xliff:g> സൃഷ്ടിക്കുന്നു"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"ബഗ് റിപ്പോർട്ട് <xliff:g id="ID">#%d</xliff:g> ക്യാപ്ചർ ചെയ്തു"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"ബഗ് റിപ്പോർട്ട് <xliff:g id="ID">#%d</xliff:g> ക്യാപ്ചർ ചെയ്തു, എന്നാൽ സ്ക്രീൻഷോട്ട് ശേഷിക്കുന്നു"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"ബഗ് റിപ്പോർട്ടിലേക്ക് വിശദാംശങ്ങൾ ചേർക്കുന്നു"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"കാത്തിരിക്കുക..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടുന്നതിന് ഇടത്തേയ്‌ക്ക് സ്വൈപ്പുചെയ്യുക"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടാൻ ടാപ്പുചെയ്യുക"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"സ്ക്രീൻഷോട്ട് കൂടാതെയോ സ്ക്രീൻഷോട്ട് പൂർത്തിയാകുന്നതിന് കാക്കാതെയോ നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടാൻ ടാപ്പുചെയ്യുക"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"സ്ക്രീൻഷോട്ട് കൂടാതെയോ സ്ക്രീൻഷോട്ട് പൂർത്തിയാകുന്നതിന് കാക്കാതെയോ നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടാൻ ടാപ്പുചെയ്യുക"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"വ്യക്തിഗതവും സ്വകാര്യവുമായ വിവരങ്ങൾ ഉൾപ്പെടെ, സിസ്റ്റത്തിന്റെ നിരവധി ലോഗ് ഫയലുകളിൽ നിന്നുള്ള ഡാറ്റ, ബഗ് റിപ്പോർട്ടുകളിൽ അടങ്ങിയിരിക്കുന്നു. നിങ്ങൾ വിശ്വസിക്കുന്ന അപ്ലിക്കേഷനുകൾക്കും ആളുകൾക്കും മാത്രം ബഗ് റിപ്പോർട്ടുകൾ പങ്കിടുക."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ഈ സന്ദേശം അടുത്ത തവണ ദൃശ്യമാക്കുക"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"ബഗ് റിപ്പോർട്ടുകൾ"</string>
diff --git a/packages/Shell/res/values-mn-rMN/strings.xml b/packages/Shell/res/values-mn-rMN/strings.xml
index cce2107..296afab 100644
--- a/packages/Shell/res/values-mn-rMN/strings.xml
+++ b/packages/Shell/res/values-mn-rMN/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Шел"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Програмд гарсан алдааны мэдээллийн <xliff:g id="ID">#%d</xliff:g> үүсгэгдэж байна"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Програмд гарсан алдааны мэдээллийн <xliff:g id="ID">#%d</xliff:g>-г бүртгэгдлээ"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Алдааны тайлан <xliff:g id="ID">#%d</xliff:g>-г илрүүлсэн хэдий ч дэлгэцээс авсан зураг хүлээгдэж байна"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Алдааны тайланд дэлгэрэнгүй мэдээлэл нэмж байна"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Түр хүлээнэ үү..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Өөрийн согог репортыг хуваалцахын тулд зүүн шудрана уу"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Програмд гарсан алдааны мэдээллээ хуваалцах бол дарна уу"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Алдааны тайлангаа дэлгэцээс авсан зураггүйгээр хуваалцах бол дарж, эсвэл дэлгэцээс авсан зургийг бэлэн болтол нь хүлээнэ үү"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Алдааны тайлангаа дэлгэцээс авсан зураггүйгээр хуваалцах бол дарж, эсвэл дэлгэцээс авсан зургийг бэлэн болтол нь хүлээнэ үү"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Алдааны репорт нь хувийн болон нууц мэдээлэл зэргийг агуулсан системийн төрөл бүрийн лог файлын датаг агуулна. Алдааны репортыг зөвхөн итгэлтэй апп болон хүмүүст хуваалцана уу."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Энэ мессежийг дараагийн удаа харуулах"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Гэмтлийн тухай тайлан"</string>
diff --git a/packages/Shell/res/values-ms-rMY/strings.xml b/packages/Shell/res/values-ms-rMY/strings.xml
index b23a382..e758745 100644
--- a/packages/Shell/res/values-ms-rMY/strings.xml
+++ b/packages/Shell/res/values-ms-rMY/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Laporan pepijat <xliff:g id="ID">#%d</xliff:g> sedang dijana"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Laporan pepijat <xliff:g id="ID">#%d</xliff:g> telah ditangkap"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Laporan pepijat <xliff:g id="ID">#%d</xliff:g> ditangkap, menunggu tngkpn skrin"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Menambahkan butiran pada laporan pepijat"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Sila tunggu…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Leret ke kiri untuk berkongsi laporan pepijat anda"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Ketik untuk berkongsi laporan pepijat anda"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Ketik untuk berkongsi laporan pepijat anda tanpa tangkapan skrin atau tunggu sehingga tangkapan skrin selesai"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Ketik untuk berkongsi laporan pepijat anda tanpa tangkapan skrin atau tunggu sehingga tangkapan skrin selesai"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Laporan pepijat mengandungi data dari pelbagai fail log sistem, termasuk maklumat peribadi dan sulit. Kongsikan laporan pepijat hanya dengan apl dan orang yang anda percayai."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Tunjukkan mesej ini pada masa akan datang"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Laporan pepijat"</string>
diff --git a/packages/Shell/res/values-my-rMM/strings.xml b/packages/Shell/res/values-my-rMM/strings.xml
index cecd20f..6f02e70 100644
--- a/packages/Shell/res/values-my-rMM/strings.xml
+++ b/packages/Shell/res/values-my-rMM/strings.xml
@@ -19,13 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"အခွံ"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ချွတ်ယွင်းမှုအစီရင်ခံချက် <xliff:g id="ID">#%d</xliff:g> ကိုထုတ်နေပါသည်"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"ချွတ်ယွင်းမှုအစီရင်ခံချက် <xliff:g id="ID">#%d</xliff:g> ကိုရယူထားပြီးပါပြီ"</string>
-    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"ချွတ်ယွင်းချက် အစီရင်ခံစာ <xliff:g id="ID">#%d</xliff:g> ဖမ်းယူထားသည် သို့သော် မျက်နှာပြင်ဓာတ်ပုံမှတ်တမ်းတင်ခြင်း စောင့်ဆိုင်းနေသည်"</string>
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"ချွတ်ယွင်းချက် အစီရင်ခံစာ <xliff:g id="ID">#%d</xliff:g> ဖမ်းယူထားသည် သို့သော် ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းတင်ခြင်း စောင့်ဆိုင်းနေသည်"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"ချွတ်ယွင်းချက်အစီရင်ခံချက်သို့ အသေးစိတ်များပေါင်းထည့်ရန်"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"ခေတ္တစောင့်ပါ..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"သင်၏ ဘာဂ် အစီရင်ခံစာကို မျှပေးရန် ဘယ်ဘက်သို့ ပွတ်ဆွဲရန်"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"သင့်ချွတ်ယွင်းမှုအစီရင်ခံချက်ကို မျှဝေရန် တို့ပါ"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"ချွတ်ယွင်းချက်အစီရင်ခံချက်ကို မျက်နှာပြင်ဓတ်ပုံမှတ်တမ်း မပါဘဲမျှဝေရန် တို့ပါ သို့မဟုတ် မျက်နှာပြင်ဓာတ်ပုံမှတ်တမ်းတင်ခြင်း ပြီးဆုံးသည်အထိ စောင့်ပါ"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"ချွတ်ယွင်းချက်အစီရင်ခံချက်ကို မျက်နှာပြင်ဓတ်ပုံမှတ်တမ်း မပါဘဲမျှဝေရန် တို့ပါ သို့မဟုတ် မျက်နှာပြင်ဓာတ်ပုံမှတ်တမ်းတင်ခြင်း ပြီးဆုံးသည်အထိ စောင့်ပါ"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"ချွတ်ယွင်းချက်အစီရင်ခံစာကို ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းမပါဘဲ မျှဝေရန် တို့ပါ သို့မဟုတ် ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းတင်ခြင်း ပြီးဆုံးသည်အထိ စောင့်ပါ"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"ချွတ်ယွင်းချက်အစီရင်ခံစာကို ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းမပါဘဲ မျှဝေရန် တို့ပါ သို့မဟုတ် ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းတင်ခြင်း ပြီးဆုံးသည်အထိ စောင့်ပါ"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"အမှားအယွင်း မှတ်တမ်းမှာ ပါရှိသော အချက်အလက်များမှာ ကိုယ်ရေးကိုယ်တာ နဲ့ လုံခြုံရေး အချက်အလက်များပါဝင်သော စနစ်မှ ပြုလုပ်မှု မှတ်တမ်းများ ဖြစ်ပါသည်၊ အမှားအယွင်း မှတ်တမ်းများကို ယုံကြည်ရသော အပလီကေးရှင်းများနဲ့ လူများကိုသာ ပေးဝေပြသမှု လုပ်ပါရန်။"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ဤစာတန်းကို နောက်တစ်ခါတွင် ပြရန်"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"ချို့ယွင်းမှု အစီရင်ခံစာများ"</string>
diff --git a/packages/Shell/res/values-pt-rBR/strings.xml b/packages/Shell/res/values-pt-rBR/strings.xml
index 438c031..2306c39 100644
--- a/packages/Shell/res/values-pt-rBR/strings.xml
+++ b/packages/Shell/res/values-pt-rBR/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"O relatório do bug <xliff:g id="ID">#%d</xliff:g> está sendo gerado"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Relatório do bug <xliff:g id="ID">#%d</xliff:g> capturado"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Relatório do bug <xliff:g id="ID">#%d</xliff:g> capturado, captura pendente"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Adicionando detalhes ao relatório do bug"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Aguarde…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Deslize para a esquerda para compartilhar seu relatório de bugs"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toque para compartilhar seu relatório do bug"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Toque para compartilhar seu relatório de bug sem captura de tela ou aguarde a conclusão"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Toque para compartilhar seu relatório de bug sem captura de tela ou aguarde a conclusão"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Os relatórios de bugs contêm dados de diversos arquivos de registro do sistema, inclusive informações pessoais e particulares. Compartilhe relatórios de bugs somente com apps e pessoas nos quais você confia."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar esta mensagem da próxima vez"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Relatórios de bugs"</string>
diff --git a/packages/Shell/res/values-pt/strings.xml b/packages/Shell/res/values-pt/strings.xml
index 438c031..2306c39 100644
--- a/packages/Shell/res/values-pt/strings.xml
+++ b/packages/Shell/res/values-pt/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"O relatório do bug <xliff:g id="ID">#%d</xliff:g> está sendo gerado"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Relatório do bug <xliff:g id="ID">#%d</xliff:g> capturado"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Relatório do bug <xliff:g id="ID">#%d</xliff:g> capturado, captura pendente"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Adicionando detalhes ao relatório do bug"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Aguarde…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Deslize para a esquerda para compartilhar seu relatório de bugs"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toque para compartilhar seu relatório do bug"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Toque para compartilhar seu relatório de bug sem captura de tela ou aguarde a conclusão"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Toque para compartilhar seu relatório de bug sem captura de tela ou aguarde a conclusão"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Os relatórios de bugs contêm dados de diversos arquivos de registro do sistema, inclusive informações pessoais e particulares. Compartilhe relatórios de bugs somente com apps e pessoas nos quais você confia."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar esta mensagem da próxima vez"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Relatórios de bugs"</string>
diff --git a/packages/Shell/res/values-ro/strings.xml b/packages/Shell/res/values-ro/strings.xml
index 43366f8..9529ade 100644
--- a/packages/Shell/res/values-ro/strings.xml
+++ b/packages/Shell/res/values-ro/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Raportul de eroare <xliff:g id="ID">#%d</xliff:g> se generează"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Raportul de eroare <xliff:g id="ID">#%d</xliff:g> a fost creat"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Raport eroare <xliff:g id="ID">#%d</xliff:g> creat, captură ecran în așteptare"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Se adaugă detaliile la raportul de eroare"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Așteptați…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Glisați la stânga pentru a trimite raportul de erori"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Atingeți pentru a trimite raportul de eroare"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Atingeți ca să trimiteți raportul de eroare fără captură de ecran sau așteptați finalizarea acesteia"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Atingeți ca să trimiteți raportul de eroare fără captură de ecran sau așteptați finalizarea acesteia"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Rapoartele despre erori conțin date din diferite fișiere de jurnal ale sistemului, inclusiv informații private și personale. Permiteți accesul la rapoartele despre erori numai aplicațiilor și persoanelor în care aveți încredere."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Afișați acest mesaj data viitoare"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Rapoarte de erori"</string>
diff --git a/packages/Shell/res/values-ru/strings.xml b/packages/Shell/res/values-ru/strings.xml
index e22ad2e..4aafbba 100644
--- a/packages/Shell/res/values-ru/strings.xml
+++ b/packages/Shell/res/values-ru/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Оболочка"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Создание отчета об ошибке <xliff:g id="ID">#%d</xliff:g>…"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Отчет об ошибке <xliff:g id="ID">#%d</xliff:g> сохранен"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Отчет об ошибке (<xliff:g id="ID">#%d</xliff:g>) готов, ожидается скриншот"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Добавление данных в отчет об ошибке"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Подождите…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Проведите влево, чтобы отправить отчет"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Нажмите, чтобы отправить отчет об ошибке."</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Нажмите, чтобы отправить отчет об ошибке сразу, или подождите, пока будет сохранен скриншот."</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Нажмите, чтобы отправить отчет об ошибке сразу, или подождите, пока будет сохранен скриншот."</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Отчеты об ошибках содержат данные различных системных журналов и могут включать личную информацию. Рекомендуем открывать к ним доступ только лицам и приложениям, заслуживающим доверие."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Показать это сообщение в следующий раз"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Отчеты об ошибках"</string>
diff --git a/packages/Shell/res/values-sl/strings.xml b/packages/Shell/res/values-sl/strings.xml
index 9419760..fdf3446 100644
--- a/packages/Shell/res/values-sl/strings.xml
+++ b/packages/Shell/res/values-sl/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Lupina"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Poročilo o napaki <xliff:g id="ID">#%d</xliff:g> je v izdelavi"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Poročilo o napaki <xliff:g id="ID">#%d</xliff:g> zajeto"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Poroč. o napakah <xliff:g id="ID">#%d</xliff:g> zajeto, posnetek zaslona nastaja"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodajanje podrobnosti v poročilo o napakah"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Počakajte ..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Povlecite v levo, če želite poslati sporočilo o napaki"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dotaknite se, če želite poročilo o napaki dati v skupno rabo"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Dotaknite se za pošiljanje poročila o napakah brez posnetka zaslona ali počakajte, da se ta dokonča"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Dotaknite se za pošiljanje poročila o napakah brez posnetka zaslona ali počakajte, da se ta dokonča"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Poročila o napakah vsebujejo podatke iz različnih dnevniških datotek sistema, vključno z osebnimi in zasebnimi podatki. Poročila o napakah delite samo z aplikacijami in ljudmi, ki jim zaupate."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Pokaži to sporočilo naslednjič"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Poročila o napakah"</string>
diff --git a/packages/Shell/res/values-sq-rAL/strings.xml b/packages/Shell/res/values-sq-rAL/strings.xml
index 206ffda..f43ce9f 100644
--- a/packages/Shell/res/values-sq-rAL/strings.xml
+++ b/packages/Shell/res/values-sq-rAL/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Guaska"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Raporti i defekteve në kod <xliff:g id="ID">#%d</xliff:g> po krijohet"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Raporti i defekteve në kod <xliff:g id="ID">#%d</xliff:g> u regjistrua"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Raporti i defekteve në kod <xliff:g id="ID">#%d</xliff:g> u regjistrua, por pamja e çastit është në pritje"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Po shtohen detajet te raporti i defekteve në kod"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Qëndro në pritje..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Rrëshqit majtas për të ndarë raportin e defektit në kod"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Trokit për të ndarë raportin e defekteve në kod"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Trokit për të ndarë raportin e defekteve në kod pa një pamje çasti ose prit që pamja e çastit të përfundojë"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Trokit për të ndarë raportin e defekteve në kod pa një pamje çasti ose prit që pamja e çastit të përfundojë"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Raportet e gabimeve përmbajnë të dhëna nga skedarë të ndryshëm ditarësh sistemi, përfshi informacione personale dhe private. Shpërndaji publikisht raportet e gabimeve vetëm me aplikacionet dhe personat që iu beson."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Tregoje këtë mesazh herën tjetër"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Raportet e gabimeve"</string>
diff --git a/packages/Shell/res/values-th/strings.xml b/packages/Shell/res/values-th/strings.xml
index ff9a647..db7f823 100644
--- a/packages/Shell/res/values-th/strings.xml
+++ b/packages/Shell/res/values-th/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"กำลังสร้างรายงานข้อบกพร่อง <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"บันทึกรายงานข้อบกพร่อง <xliff:g id="ID">#%d</xliff:g> แล้ว"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"จับภาพรายงานข้อบกพร่อง <xliff:g id="ID">#%d</xliff:g> แล้วแต่ภาพหน้าจอยังไม่เสร็จ"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"กำลังเพิ่มรายละเอียดในรายงานข้อบกพร่อง"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"โปรดรอสักครู่…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"กวาดไปทางซ้ายเพื่อแชร์รายงานข้อบกพร่อง"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"แตะเพื่อแชร์รายงานข้อบกพร่องของคุณ"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"แตะเพื่อแชร์รายงานข้อบกพร่องของคุณโดยไม่มีภาพหน้าจอ หรือรอให้ภาพหน้าจอเสร็จสมบูรณ์"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"แตะเพื่อแชร์รายงานข้อบกพร่องของคุณโดยไม่มีภาพหน้าจอ หรือรอให้ภาพหน้าจอเสร็จสมบูรณ์"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"รายงานข้อบกพร่องมีข้อมูลจากไฟล์บันทึกต่างๆ ของระบบ รวมถึงข้อมูลส่วนตัว แชร์รายงานข้อบกพร่องกับแอปและบุคคลที่คุณไว้ใจเท่านั้น"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"แสดงข้อความนี้ในครั้งต่อไป"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"รายงานข้อบกพร่อง"</string>
diff --git a/packages/Shell/res/values-tl/strings.xml b/packages/Shell/res/values-tl/strings.xml
index 9e152d3..f99a1b8 100644
--- a/packages/Shell/res/values-tl/strings.xml
+++ b/packages/Shell/res/values-tl/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Binubuo na ang ulat ng bug na <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Na-capture ang ulat ng bug na <xliff:g id="ID">#%d</xliff:g>"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Nakunan ang ulat ng bug <xliff:g id="ID">#%d</xliff:g>, nakabinbin ang screenshot"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Pagdaragdag ng mga detalye sa ulat ng bug"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Mangyaring maghintay..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Mag-swipe pakaliwa upang ibahagi ang iyong ulat ng bug"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Mag-tap upang ibahagi ang iyong ulat ng bug"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Mag-tap para ibahagi ang iyong ulat ng bug nang walang screenshot o hintaying matapos ang screenshot"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Mag-tap para ibahagi ang iyong ulat ng bug nang walang screenshot o hintaying matapos ang screenshot"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Naglalaman ang mga ulat ng bug ng data mula sa iba\'t ibang file ng log ng system, kabilang ang personal at pribadong impormasyon. Magbahagi lang ng mga ulat ng bug sa apps at mga tao na pinagkakatiwalaan mo."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Ipakita ang mensaheng ito sa susunod"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Mga ulat sa bug"</string>
diff --git a/packages/Shell/res/values-tr/strings.xml b/packages/Shell/res/values-tr/strings.xml
index 4c765da..be448af 100644
--- a/packages/Shell/res/values-tr/strings.xml
+++ b/packages/Shell/res/values-tr/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Kabuk"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Hata raporu (<xliff:g id="ID">#%d</xliff:g>) oluşturuluyor"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Hata raporu (<xliff:g id="ID">#%d</xliff:g>) yakalandı"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"<xliff:g id="ID">#%d</xliff:g> hata raporu yakalandı, ekran görüntüsü bekleniyor"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Hata raporuna ayrıntılar ekleniyor"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Lütfen bekleyin…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Hata raporunuzu paylaşmak için hızlıca sola kaydırın"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Hata raporunuzu paylaşmak için hafifçe dokunun"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Hata raporunu ekran görüntüsüz paylaşmak için dokunun veya bitirmek için ekran görüntüsünü bekleyin"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Hata raporunu ekran görüntüsüz paylaşmak için dokunun veya bitirmek için ekran görüntüsünü bekleyin"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Hata raporları, kişisel ve özel bilgiler dahil olmak üzere sistemin çeşitli günlük dosyalarından veriler içerir. Hata raporlarını sadece güvendiğiniz uygulamalar ve kişilerle paylaşın."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Bir dahaki sefere bu iletiyi göster"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Hata raporları"</string>
diff --git a/packages/Shell/res/values-ur-rPK/strings.xml b/packages/Shell/res/values-ur-rPK/strings.xml
index edc7433..ef6801f 100644
--- a/packages/Shell/res/values-ur-rPK/strings.xml
+++ b/packages/Shell/res/values-ur-rPK/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"شیل"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"بگ رپورٹ <xliff:g id="ID">#%d</xliff:g> تخلیق ہو رہی ہے"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"بگ رپورٹ <xliff:g id="ID">#%d</xliff:g> کیپچر ہو گئی"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"بگ رپورٹ <xliff:g id="ID">#%d</xliff:g> کیپچر ہو گیا مگر اسکرین شاٹ زیر التواء"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"بگ رپورٹ میں تفصیلات شامل کی جا رہی ہیں"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"براہ کرم انتظار کریں…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"اپنی بگ رپورٹ کا اشتراک کرنے کیلئے بائیں سوائپ کریں"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"اپنی بگ رپورٹ کا اشتراک کرنے کیلئے تھپتھپائیں"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"بغیر اسکرین شاٹ کے بگ رپورٹ کا اشتراک کرنے کیلئے تھپتھپائیں یا اسکرین شاٹ کے ختم ہونے کا انتظار کریں"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"بغیر اسکرین شاٹ کے بگ رپورٹ کا اشتراک کرنے کیلئے تھپتھپائیں یا اسکرین شاٹ کے ختم ہونے کا انتظار کریں"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"بَگ رپورٹس میں سسٹم کی مختلف لاگ فائلوں سے ڈیٹا شامل ہوتا ہے، بشمول ذاتی اور نجی معلومات۔ بَگ رپورٹس کا اشتراک صرف اپنے بھروسے مند ایپس اور لوگوں کے ساتھ کریں۔"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"یہ پیغام اگلی بار دکھائیں"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"بگ رپورٹس"</string>
diff --git a/packages/Shell/res/values-uz-rUZ/strings.xml b/packages/Shell/res/values-uz-rUZ/strings.xml
index 90d7718..c1a1948 100644
--- a/packages/Shell/res/values-uz-rUZ/strings.xml
+++ b/packages/Shell/res/values-uz-rUZ/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Terminal"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Xatoliklar hisoboti (<xliff:g id="ID">#%d</xliff:g>) tayyorlanmoqda"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Xatoliklar hisoboti (<xliff:g id="ID">#%d</xliff:g>) yozib olindi"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Xatoliklar hisoboti (<xliff:g id="ID">#%d</xliff:g>) tayyor, skrinshot kutilmoqda"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Xatoliklar hisobotiga tafsilotlar qo‘shilmoqda"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Iltimos, kuting…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Xatolik hisobotini yuborish uchun barmog‘ingiz bilan chapga suring"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Xatoliklar hisobotini ulashish uchun bosing"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Xatoliklar hisobotini darhol yuborish uchun bosing yoki skrinshot saqlanguncha kuting"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Xatoliklar hisobotini darhol yuborish uchun bosing yoki skrinshot saqlanguncha kuting"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Xatolik hisobotlari tizimdagi har xil jurnal fayllardagi ma’lumotlarni, shuningdek, shaxsiy hamda maxfiy ma’lumotlarni o‘z ichiga oladi. Xatolik hisobotlarini faqat ishonchli dasturlar va odamlar bilan bo‘lishing."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Ushbu xabar keyingi safar ko‘rsatilsin"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Xatoliklar hisoboti"</string>
diff --git a/packages/Shell/res/values-vi/strings.xml b/packages/Shell/res/values-vi/strings.xml
index cb8c5b9..2229991 100644
--- a/packages/Shell/res/values-vi/strings.xml
+++ b/packages/Shell/res/values-vi/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Báo cáo lỗi <xliff:g id="ID">#%d</xliff:g> đang được tạo"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"Đã chụp báo cáo lỗi <xliff:g id="ID">#%d</xliff:g>"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Đã chụp báo cáo lỗi <xliff:g id="ID">#%d</xliff:g>, đang chờ ảnh chụp màn hình"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Đang thêm thông tin chi tiết vào báo cáo lỗi"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Vui lòng đợi…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Vuốt sang trái để chia sẻ báo cáo lỗi của bạn"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Nhấn để chia sẻ báo cáo lỗi của bạn"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Bấm để chia sẻ báo cáo lỗi mà không cần ảnh chụp màn hình hoặc đợi hoàn tất ảnh chụp màn hình"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Bấm để chia sẻ báo cáo lỗi mà không cần ảnh chụp màn hình hoặc đợi hoàn tất ảnh chụp màn hình"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Các báo cáo lỗi chứa dữ liệu từ nhiều tệp nhật ký khác nhau của hệ thống, bao gồm cả thông tin cá nhân và riêng tư. Chỉ chia sẻ báo cáo lỗi với các ứng dụng và những người mà bạn tin tưởng."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Hiển thị thông báo này vào lần tới"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Báo cáo lỗi"</string>
diff --git a/packages/Shell/res/values-zh-rCN/strings.xml b/packages/Shell/res/values-zh-rCN/strings.xml
index 6e13d75..b09a7d0 100644
--- a/packages/Shell/res/values-zh-rCN/strings.xml
+++ b/packages/Shell/res/values-zh-rCN/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"正在生成错误报告 <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"已捕获错误报告 <xliff:g id="ID">#%d</xliff:g>"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"已捕获错误报告 <xliff:g id="ID">#%d</xliff:g>,但仍在等待屏幕截图完成"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"正在向错误报告添加详细信息"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"请稍候…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"向左滑动即可分享错误报告"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"点按即可分享您的错误报告"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"点按即可分享不含屏幕截图的错误报告;您也可以等待屏幕截图完成"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"点按即可分享不含屏幕截图的错误报告;您也可以等待屏幕截图完成"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"错误报告包含的数据来自于系统的各个日志文件,其中包含个人信息和隐私信息。请务必只与您信任的应用和用户分享错误报告。"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"下次再显示这条讯息"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"错误报告"</string>
diff --git a/packages/Shell/res/values-zh-rHK/strings.xml b/packages/Shell/res/values-zh-rHK/strings.xml
index 7ade56b..384eee7 100644
--- a/packages/Shell/res/values-zh-rHK/strings.xml
+++ b/packages/Shell/res/values-zh-rHK/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"命令介面"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"正在產生錯誤報告 <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"已擷取錯誤報告 <xliff:g id="ID">#%d</xliff:g>"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"已擷取錯誤報告 <xliff:g id="ID">#%d</xliff:g>,但螢幕畫面仍未擷取完成"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"正在新增錯誤報告詳細資訊"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"請稍候…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"向左滑動即可分享錯誤報告"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"輕按即可分享錯誤報告"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"輕按以分享錯誤報告 (不包含螢幕擷圖),或等待螢幕畫面擷取完成"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"輕按以分享錯誤報告 (不包含螢幕擷圖),或等待螢幕畫面擷取完成"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"錯誤報告中有來自系統各個記錄檔案的資料,包括個人和私人資料。請只與您信任的應用程式和使用者分享錯誤報告。"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"下次再顯示這則訊息"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"錯誤報告"</string>
diff --git a/packages/Shell/res/values-zh-rTW/strings.xml b/packages/Shell/res/values-zh-rTW/strings.xml
index 8695d5f..2702bad 100644
--- a/packages/Shell/res/values-zh-rTW/strings.xml
+++ b/packages/Shell/res/values-zh-rTW/strings.xml
@@ -19,16 +19,13 @@
     <string name="app_label" msgid="3701846017049540910">"殼層"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"正在產生錯誤報告 <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"已擷取錯誤報告 <xliff:g id="ID">#%d</xliff:g>"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"錯誤報告 <xliff:g id="ID">#%d</xliff:g> 擷取成功,但螢幕畫面尚未擷取完畢"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"正在新增錯誤報告詳細資訊"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"請稍候…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"向左滑動即可分享錯誤報告"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"輕按即可分享錯誤報告"</string>
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
-    <skip />
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"輕觸即可分享無螢幕擷圖的錯誤報告;您也可以等候螢幕畫面擷取完畢"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"輕觸即可分享無螢幕擷圖的錯誤報告;您也可以等候螢幕畫面擷取完畢"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"錯誤報告的資料來自系統各個紀錄檔,包括個人和私密資訊。請務必只與您信任的應用程式和使用者分享錯誤報告。"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"下次仍顯示這則訊息"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"錯誤報告"</string>
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 10c5416..89ebcd1 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -1102,7 +1102,14 @@
             preferredDomain = "@" + preferredDomain;
         }
 
-        final Account[] accounts = am.getAccounts();
+        final Account[] accounts;
+        try {
+            accounts = am.getAccounts();
+        } catch (RuntimeException e) {
+            Log.e(TAG, "Could not get accounts for preferred domain " + preferredDomain, e);
+            return null;
+        }
+        if (DEBUG) Log.d(TAG, "Number of accounts: " + accounts.length);
         Account foundAccount = null;
         for (Account account : accounts) {
             if (Patterns.EMAIL_ADDRESS.matcher(account.name).matches()) {
diff --git a/packages/Shell/src/com/android/shell/BugreportReceiver.java b/packages/Shell/src/com/android/shell/BugreportReceiver.java
index 9afa900..cbd17bf 100644
--- a/packages/Shell/src/com/android/shell/BugreportReceiver.java
+++ b/packages/Shell/src/com/android/shell/BugreportReceiver.java
@@ -51,6 +51,7 @@
 
     @Override
     public void onReceive(Context context, Intent intent) {
+        Log.d(TAG, "onReceive: " + intent);
         // Clean up older bugreports in background
         cleanupOldFiles(this, intent, INTENT_BUGREPORT_FINISHED, MIN_KEEP_COUNT, MIN_KEEP_AGE);
 
diff --git a/packages/SystemUI/res/layout/tv_pip_onboarding.xml b/packages/SystemUI/res/layout/tv_pip_onboarding.xml
index f031bb4..b0814cf 100644
--- a/packages/SystemUI/res/layout/tv_pip_onboarding.xml
+++ b/packages/SystemUI/res/layout/tv_pip_onboarding.xml
@@ -37,10 +37,13 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="24dp"
+        android:paddingStart="24dp"
+        android:paddingEnd="24dp"
         android:fontFamily="sans-serif"
         android:textSize="16sp"
         android:textColor="#EEEEEE"
         android:lineSpacingMultiplier="1.28"
+        android:gravity="top|center_horizontal"
         android:text="@string/pip_onboarding_description" />
     <Button
         android:id="@+id/close"
diff --git a/packages/SystemUI/res/layout/tv_pip_overlay.xml b/packages/SystemUI/res/layout/tv_pip_overlay.xml
index 40c6fa1..1ba423b 100644
--- a/packages/SystemUI/res/layout/tv_pip_overlay.xml
+++ b/packages/SystemUI/res/layout/tv_pip_overlay.xml
@@ -24,13 +24,19 @@
     <TextView
         android:id="@+id/guide_overlay"
         android:layout_width="match_parent"
-        android:layout_height="32dp"
+        android:layout_height="wrap_content"
         android:layout_alignParentBottom="true"
+        android:paddingTop="6dp"
+        android:paddingBottom="6dp"
+        android:paddingStart="10dp"
+        android:paddingEnd="10dp"
         android:textSize="14sp"
         android:textColor="#EEEEEE"
         android:fontFamily="sans-serif"
         android:background="@drawable/tv_pip_overlay_background"
+        android:lineSpacingMultiplier="1.465"
         android:gravity="center"
+        android:maxLines="2"
         android:text="@string/pip_hold_home" />
     <LinearLayout
         android:id="@+id/guide_buttons"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 70247ee..7d85ef6 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -73,6 +73,7 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Skermkiekie geneem."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Raak om jou skermkiekie te sien."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Kon nie skermkiekie neem nie."</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Kon nie skermkiekie stoor nie."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Kan weens beperkte bergingspasie nie skermkiekie stoor nie."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Die program of jou organisasie laat nie toe dat skermkiekies geneem word nie."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB-lêeroordrag-opsies"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 226d7f5..e870ea7 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -73,6 +73,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_to_save_unknown_text" msgid="7887826345701753830">"ቅጽበታዊ ገጽ ዕይታን በማስቀመጥ ጊዜ ችግር አጋጥሟል።"</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"ባለው የተገደበ የማከማቻ ቦታ ምክንያት ቅጽበታዊ ገጽ ዕይታን ማስቀመጥ አይችልም።"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ቅጽበታዊ ገጽ እይታዎችን ማንሳት በመተግበሪያው ወይም በእርስዎ ድርጅት አይፈቀድም።"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"የUSB ፋይል ሰደዳ አማራጮች"</string>
diff --git a/packages/SystemUI/res/values-am/strings_tv.xml b/packages/SystemUI/res/values-am/strings_tv.xml
index a6b9660..544ae07 100644
--- a/packages/SystemUI/res/values-am/strings_tv.xml
+++ b/packages/SystemUI/res/values-am/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"PIPን ዝጋ"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"ሙሉ ማያ ገጽ"</string>
     <string name="pip_play" msgid="674145557658227044">"አጫውት"</string>
     <string name="pip_pause" msgid="8412075640017218862">"ለአፍታ አቁም"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"PIPን ለመቆጣጠር "<b>"መነሻ"</b>"ን ይያዙ"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"PIPን ለመቆጣጠር የመነሻ\nአዝራሩን ይጫኑ እና ይያዙ"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"ገባኝ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 5dc3b01..100bc63 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -77,6 +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_to_save_unknown_text" msgid="7887826345701753830">"حدثت مشكلة أثناء حفظ لقطة الشاشة."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"يتعذر حفظ لقطة الشاشة نظرًا لأن مساحة التخزين المتاحة محدودة."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"غير مسموح بالتقاط لقطات شاشة نظرًا لإذن يتعلق بالتطبيق أو بالمؤسسة."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"‏خيارات نقل الملفات عبر USB"</string>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index 21bdc45..7763cb3 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -73,6 +73,7 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Skrinşot çəkildi."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Skrinşotunuza baxmaq üçün toxunun"</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Skrinşot götürülə bilinmədi."</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Skrinşot yadda saxlanarkən problem baş verdi."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Yaddaş ehtiyatının az olması səbəbindən skrinşotu yadda saxlamaq olmur."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Tətbiq və ya təşkilatınız tərəfindən skrinşot çəkməyə icazə verilmir."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB fayl transferi seçimləri"</string>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings_tv.xml b/packages/SystemUI/res/values-az-rAZ/strings_tv.xml
index e4e35ab2..6751bc9 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings_tv.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"PIP bağlayın"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Tam ekran"</string>
     <string name="pip_play" msgid="674145557658227044">"Göstərin"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Fasilə verin"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"PIP idarı etmək üçün "<b>"Əsas səhifəni"</b>" tutub saxlayın"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP idarə etmək üçün Əsas səhifə\n düyməsini basıb saxlayın"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Anladım"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 969b378..1198950 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -74,6 +74,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Snimak ekrana je napravljen."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Dodirnite da biste videli snimak ekrana."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Nije moguće napraviti snimak ekrana."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Čuvanje snimka ekrana nije uspelo zbog ograničenog memorijskog prostora."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Aplikacija ili organizacija ne dozvoljavaju pravljenje snimaka ekrana."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opcije USB prenosa datoteka"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 9ff5f95..876af0a 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -73,6 +73,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_to_save_unknown_text" msgid="7887826345701753830">"При запазването на екранната снимка възникна проблем."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Екранната снимка не може да се запази поради ограничено място в хранилището."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Правенето на екранни снимки не е разрешено от приложението или организацията ви."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Опции за пренос на файлове чрез USB"</string>
diff --git a/packages/SystemUI/res/values-bg/strings_tv.xml b/packages/SystemUI/res/values-bg/strings_tv.xml
index c5fc5b1..38c10ab 100644
--- a/packages/SystemUI/res/values-bg/strings_tv.xml
+++ b/packages/SystemUI/res/values-bg/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Затваряне на PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Цял екран"</string>
     <string name="pip_play" msgid="674145557658227044">"Пускане"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Пауза"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Контр. на PIP: Задр. "<b>"HOME"</b></string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"За контролиране на PIP\nнатиснете и задръжте HOME"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Разбрах"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index 66537da..eaf450f 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -73,6 +73,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_to_save_unknown_text" msgid="7887826345701753830">"স্ক্রীনশট সংরক্ষণের সময়ে সমস্যা হয়েছে৷"</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"সঞ্চয়স্থান সীমিত থাকায় স্ক্রীনশটটি সংরক্ষণ করা যাবে না৷"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"অ্যাপ্লিকেশান বা আপনার প্রতিষ্ঠান স্ক্রীনশটগুলি নেওয়া অনুমতি দেয়নি৷"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB ফাইল স্থানান্তরের বিকল্পগুলি"</string>
diff --git a/packages/SystemUI/res/values-bs-rBA/strings.xml b/packages/SystemUI/res/values-bs-rBA/strings.xml
index 91d9dea..3befd44 100644
--- a/packages/SystemUI/res/values-bs-rBA/strings.xml
+++ b/packages/SystemUI/res/values-bs-rBA/strings.xml
@@ -74,6 +74,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Ekran snimljen."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Dodirnite za prikaz snimka ekrana."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Došlo je do greške prilikom snimanja ekrana."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Snimak ekrana se ne može sačuvati zbog manjka prostora za pohranu."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Aplikacija ili vaša organizacija ne dopuštaju pravljenje snimaka ekrana."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opcije USB prijenosa fajlova"</string>
diff --git a/packages/SystemUI/res/values-bs-rBA/strings_tv.xml b/packages/SystemUI/res/values-bs-rBA/strings_tv.xml
new file mode 100644
index 0000000..1719318
--- /dev/null
+++ b/packages/SystemUI/res/values-bs-rBA/strings_tv.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_close" msgid="3480680679023423574">"Zatvori PIP"</string>
+    <!-- no translation found for pip_fullscreen (8604643018538487816) -->
+    <skip />
+    <!-- no translation found for pip_play (674145557658227044) -->
+    <skip />
+    <!-- no translation found for pip_pause (8412075640017218862) -->
+    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Za kontr. PIP držite "<b>"HOME"</b></string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Za kontrolu PIP \n držite dugme POČETAK"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Jasno mi je"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index a758798..42596fe 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"S\'ha fet una captura de pantalla."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Toca per veure la captura de pantalla."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"No s\'ha pogut fer una captura de pantalla."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"La captura de pantalla no es pot desar perquè no hi ha prou espai d\'emmagatzematge."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"L\'aplicació o l\'organització no permeten fer captures de pantalla."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opcions transf. fitxers USB"</string>
diff --git a/packages/SystemUI/res/values-ca/strings_tv.xml b/packages/SystemUI/res/values-ca/strings_tv.xml
index c5779ae..1aed2b4 100644
--- a/packages/SystemUI/res/values-ca/strings_tv.xml
+++ b/packages/SystemUI/res/values-ca/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Tanca PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Pantalla completa"</string>
     <string name="pip_play" msgid="674145557658227044">"Reprodueix"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Posa en pausa"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Prem "<b>"INICI"</b>" per contr. PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Mantén premut botó INICI\n per controlar PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"D\'acord"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 86353a6..3867673 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -75,6 +75,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Snímek obrazovky Snímek obrazovky pořízen."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Snímek obrazovky zobrazíte dotykem."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Snímek obrazovky se nepodařilo zachytit."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Snímek obrazovky nelze pořídit kvůli nedostatku místa v úložišti."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Aplikace nebo organizace zakazuje pořizování snímků obrazovky."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Možnosti přenosu souborů pomocí rozhraní USB"</string>
diff --git a/packages/SystemUI/res/values-cs/strings_tv.xml b/packages/SystemUI/res/values-cs/strings_tv.xml
index 89640cd..2480c37 100644
--- a/packages/SystemUI/res/values-cs/strings_tv.xml
+++ b/packages/SystemUI/res/values-cs/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Ukončit PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Celá obrazovka"</string>
     <string name="pip_play" msgid="674145557658227044">"Přehrát"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Pozastavit"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Funkci PIP lze ovládat podržením tlačítka "<b>"PLOCHA"</b></string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Funkci PIP lze ovládat\npodržením tlačítka PLOCHA"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Rozumím"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 55fefc2..0356a18 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Skærmbilledet er gemt."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Tryk for at se dit skærmbillede."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Skærmbilledet kunne ikke tages."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Skærmbilledet kan ikke gemmes pga. begrænset lagerplads."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Appen eller din organisation tillader ikke, at du tager skærmbilleder."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Muligheder for USB-filoverførsel"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index cb8e0fd..7e7b2ac 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot aufgenommen"</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Zum Ansehen berühren"</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Screenshot konnte nicht aufgenommen werden."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Speichern des Screenshots aufgrund von zu wenig Speicher nicht möglich."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Die App oder Ihr Unternehmen lässt das Erstellen von Screenshots nicht zu."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB-Dateiübertragungsoptionen"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index b1df615..943c67d 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -73,6 +73,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_to_save_unknown_text" msgid="7887826345701753830">"Παρουσιάστηκε πρόβλημα κατά την αποθήκευση του στιγμιότυπου οθόνης."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Δεν είναι δυνατή η αποθήκευση του στιγμιότυπου οθόνης λόγω περιορισμένου χώρου αποθήκευσης."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Η λήψη στιγμιοτύπων οθόνης δεν επιτρέπεται από την εφαρμογή ή από τον οργανισμό σας."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Επιλογές μεταφοράς αρχείων μέσω USB"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 72c71a8..6367ed9 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -73,6 +73,7 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot captured."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Touch to view your screenshot."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Couldn\'t capture screenshot."</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Problem encountered while saving screenshot."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Can\'t save screenshot due to limited storage space."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Taking screenshots is not allowed by the app or your organisation."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB file transfer options"</string>
@@ -220,10 +221,8 @@
     <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Work mode on."</string>
     <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Work mode turned off."</string>
     <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Work mode turned on."</string>
-    <!-- no translation found for accessibility_quick_settings_data_saver_changed_off (650231949881093289) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_data_saver_changed_on (4218725402373934151) -->
-    <skip />
+    <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Data Saver turned off."</string>
+    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Data Saver turned on."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G data is paused"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G data is paused"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 72c71a8..6367ed9 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -73,6 +73,7 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot captured."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Touch to view your screenshot."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Couldn\'t capture screenshot."</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Problem encountered while saving screenshot."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Can\'t save screenshot due to limited storage space."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Taking screenshots is not allowed by the app or your organisation."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB file transfer options"</string>
@@ -220,10 +221,8 @@
     <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Work mode on."</string>
     <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Work mode turned off."</string>
     <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Work mode turned on."</string>
-    <!-- no translation found for accessibility_quick_settings_data_saver_changed_off (650231949881093289) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_data_saver_changed_on (4218725402373934151) -->
-    <skip />
+    <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Data Saver turned off."</string>
+    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Data Saver turned on."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G data is paused"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G data is paused"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 72c71a8..6367ed9 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -73,6 +73,7 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot captured."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Touch to view your screenshot."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Couldn\'t capture screenshot."</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Problem encountered while saving screenshot."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Can\'t save screenshot due to limited storage space."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Taking screenshots is not allowed by the app or your organisation."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB file transfer options"</string>
@@ -220,10 +221,8 @@
     <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Work mode on."</string>
     <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Work mode turned off."</string>
     <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Work mode turned on."</string>
-    <!-- no translation found for accessibility_quick_settings_data_saver_changed_off (650231949881093289) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_data_saver_changed_on (4218725402373934151) -->
-    <skip />
+    <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Data Saver turned off."</string>
+    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Data Saver turned on."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G data is paused"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G data is paused"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 34e5a7e..e60fd2e 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Se guardó la captura de pantalla."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Toca para ver tu captura de pantalla."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"No se pudo guardar la captura de pantalla."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"No se puede guardar la captura de pantalla debido al almacenamiento limitado."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"La app o tu organización no permiten las capturas de pantalla."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opciones de transferencia de archivos por USB"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings_tv.xml b/packages/SystemUI/res/values-es-rUS/strings_tv.xml
index 16d9f36..1df219d 100644
--- a/packages/SystemUI/res/values-es-rUS/strings_tv.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Cerrar PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Pantalla completa"</string>
     <string name="pip_play" msgid="674145557658227044">"Reproducir"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Pausar"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Mantén presionado "<b>"INICIO"</b>" para controlar PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Mantén presionado botón\nINICIO para controlar PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Entendido"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 2698ffc..e387019 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Captura guardada"</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Toca para ver la captura de pantalla"</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"No se ha podido guardar la captura de pantalla."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"No se puede guardar la captura de pantalla porque no hay espacio de almacenamiento suficiente."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"La aplicación o tu organización no permiten que se realicen capturas de pantalla."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opciones de transferencia de archivos por USB"</string>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 42d449a..7e68757 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Ekraanipilt on jäädvustatud."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Puudutage kuvatõmmise vaatamiseks."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Kuvatõmmist ei saanud jäädvustada."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Piiratud salvestusruumi tõttu ei saa ekraanipilti salvestada."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Rakendus või teie organisatsioon ei luba ekraanipilte jäädvustada."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB-failiedastuse valikud"</string>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index 67f13cc..6a358d4 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Pantaila-argazkia atera da."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Pantaila-argazkia ikusteko, ukitu ezazu."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Ezin izan da pantaila-argazkia atera."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Ezin da atera pantaila-argazkia ez delako tokirik geratzen."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Aplikazioak edo erakundeak ez du onartzen pantaila-argazkiak ateratzea."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB fitxategiak transferitzeko aukerak"</string>
diff --git a/packages/SystemUI/res/values-eu-rES/strings_tv.xml b/packages/SystemUI/res/values-eu-rES/strings_tv.xml
index e6bbd32..80feff6 100644
--- a/packages/SystemUI/res/values-eu-rES/strings_tv.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Itxi PIPa"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Pantaila osoa"</string>
     <string name="pip_play" msgid="674145557658227044">"Erreproduzitu"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Pausatu"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109"><b>"HASIERA"</b>" PIP kontrolatzeko"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Eduki sakatuta HASIERA\nPIPa kontrolatzeko"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Ados"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 13c9132..2477a12 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"عکس صفحه‌نمایش گرفته شد."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"برای مشاهده عکس صفحه‌نمایشتان، لمس کنید."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"عکس صفحه‌نمایش گرفته نشد."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"به دلیل محدود بودن فضای ذخیره‌سازی نمی‌توانید عکس صفحه‌نمایش را ذخیره کنید."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"این برنامه یا سازمان شما اجازه نمی‌دهند عکس صفحه‌نمایش بگیرید."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"‏گزینه‌های انتقال فایل USB"</string>
@@ -510,9 +512,9 @@
     <string name="headset" msgid="4534219457597457353">"هدست"</string>
     <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"هدفون وصل شد"</string>
     <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"هدست وصل شد"</string>
-    <string name="data_saver" msgid="5037565123367048522">"صرفه‌جویی در مصرف داده"</string>
-    <string name="accessibility_data_saver_on" msgid="8454111686783887148">"صرفه‌جویی در مصرف داده روشن است"</string>
-    <string name="accessibility_data_saver_off" msgid="8841582529453005337">"صرفه‌جویی در مصرف داده خاموش است"</string>
+    <string name="data_saver" msgid="5037565123367048522">"صرفه‌جویی داده"</string>
+    <string name="accessibility_data_saver_on" msgid="8454111686783887148">"صرفه‌جویی داده روشن است"</string>
+    <string name="accessibility_data_saver_off" msgid="8841582529453005337">"صرفه‌جویی داده خاموش است"</string>
     <string name="switch_bar_on" msgid="1142437840752794229">"روشن"</string>
     <string name="switch_bar_off" msgid="8803270596930432874">"خاموش"</string>
     <string name="nav_bar" msgid="1993221402773877607">"نوار پیمایش"</string>
diff --git a/packages/SystemUI/res/values-fa/strings_tv.xml b/packages/SystemUI/res/values-fa/strings_tv.xml
index 6a62f12..5130b50 100644
--- a/packages/SystemUI/res/values-fa/strings_tv.xml
+++ b/packages/SystemUI/res/values-fa/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"‏بستن PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"تمام صفحه"</string>
     <string name="pip_play" msgid="674145557658227044">"پخش"</string>
     <string name="pip_pause" msgid="8412075640017218862">"مکث"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"‏کنترل PIP ‏با نگه‌داشتن "<b>"HOME"</b></string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"‏برای کنترل PIP دکمه صفحه\nاصلی را فشار دهید و نگه‌دارید"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"متوجه شدم"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index e5ddaad..6199536 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Kuvakaappaus tallennettu"</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Katso kuvakaappaus koskettamalla."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Kuvakaappausta ei voitu tallentaa"</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Kuvakaappauksen tallentaminen epäonnistui, sillä tallennustilaa ei ole riittävästi."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Sovellus tai organisaatiosi ei salli kuvakaappauksien tallentamista."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB-tiedostonsiirtoasetukset"</string>
diff --git a/packages/SystemUI/res/values-fi/strings_tv.xml b/packages/SystemUI/res/values-fi/strings_tv.xml
index c19894f..a42c231 100644
--- a/packages/SystemUI/res/values-fi/strings_tv.xml
+++ b/packages/SystemUI/res/values-fi/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Sulje PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Koko näyttö"</string>
     <string name="pip_play" msgid="674145557658227044">"Toista"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Keskeytä"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"PIP: paina pitkään "<b>"aloituspain"</b>"."</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Hallinnoi PIP:tä: paina\naloitusnäyttöpainiketta pitkään."</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Selvä"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 8ad463b..6ed42ed 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Capture d\'écran réussie"</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Appuyez pour afficher votre capture d\'écran."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Impossible de réaliser une capture d\'écran"</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Impossible d\'enregistrer la saisie d\'écran, car l\'espace de stockage est limité."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"L\'application ou votre organisation n\'autorise pas les saisies d\'écran."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Options transfert fichiers USB"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
index 9165632..29e94c6 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Fermer mode IDI"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Plein écran"</string>
     <string name="pip_play" msgid="674145557658227044">"Lecture"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Interrompre"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Maint. enf. "<b>"ACC."</b>" pr gér. mode IDI"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Maint. enf. \nACCUEIL pr gér. mode IDI"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index b520a88..c08958d 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Capture d\'écran réussie"</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Appuyez pour afficher votre capture d\'écran."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Impossible de réaliser une capture d\'écran"</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Impossible d\'enregistrer la capture d\'écran, car l\'espace de stockage est limité."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Les captures d\'écran ne sont pas autorisées par l\'application ou par votre organisation."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Options transfert fichiers USB"</string>
diff --git a/packages/SystemUI/res/values-fr/strings_tv.xml b/packages/SystemUI/res/values-fr/strings_tv.xml
index bc4bd22..8504a8e 100644
--- a/packages/SystemUI/res/values-fr/strings_tv.xml
+++ b/packages/SystemUI/res/values-fr/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Fermer mode PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Plein écran"</string>
     <string name="pip_play" msgid="674145557658227044">"Lire"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Suspendre"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Appui long "<b>"ACCUEIL"</b>" pour contrôler PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Appui long bouton ACCUEIL\npour contrôler PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index 1dc47d5..7cb3cb1 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Captura de pantalla gardada."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Toca para ver a captura de pantalla."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Non se puido facer a captura de pantalla."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Non se pode gardar a captura de pantalla porque o espazo de almacenamento é limitado."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"A aplicación ou a túa organización non permite realizar capturas de pantalla."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opcións de transferencia USB"</string>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml
index 57a95cd..a8394a2 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -73,6 +73,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_to_save_unknown_text" msgid="7887826345701753830">"સ્ક્રીનશૉટ સાચવવામાં સમયા આવી."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"મર્યાદિત સંગ્રહ સ્થાનને કારણે સ્ક્રીનશોટ સાચવી શકાતો નથી."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ઍપ્લિકેશન કે તમારી સંસ્થા દ્વારા સ્ક્રીનશોટ્સ લેવાની મંજૂરી નથી."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB ફાઇલ ટ્રાન્સફર વિકલ્પો"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 0c3cb48..7618c02 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"स्‍क्रीनशॉट कैप्‍चर किया गया."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"अपना स्‍क्रीनशॉट देखने के लिए स्‍पर्श करें."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"स्क्रीनशॉट को कैप्चर नहीं किया जा सका."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"सीमित मेमोरी स्थान के कारण स्क्रीनशॉट सहेजा नहीं जा सकता."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"आपके ऐप्लिकेशन या आपके संगठन द्वारा स्क्रीनशॉट लेने की अनुमति नहीं है."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB फ़ाइल स्थानांतरण विकल्प"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 81f10a2..715f667 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -74,6 +74,7 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Zaslon je snimljen."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Dodirnite za prikaz snimke zaslona."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Nije bilo moguće snimiti zaslon."</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Prilikom spremanja snimke zaslona pojavio se problem."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Zaslon nije snimljen zbog ograničenog prostora za pohranu."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Snimanje zaslona ne dopušta aplikacija ili vaša organizacija."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opcije USB prijenosa datoteka"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index ccf582b..280cdb6 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -73,6 +73,7 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Képernyőkép rögzítve."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Megérintésével megtekintheti a képernyőképet."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Nem sikerült rögzíteni a képernyőképet."</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Hiba történt a képernyőkép mentése során."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Nem menthet képernyőképet, mert kevés a tárhely."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Az alkalmazás vagy szervezete nem engedélyezi képernyőképek készítését."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB-fájlátvitel beállításai"</string>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index e60ce28..bf9f80d 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Էկրանի հանույթը լուսանկարվել է:"</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Հպեք ձեր էկրանի հանույթը տեսնելու համար:"</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Չհաջողվեց լուսանկարել էկրանի հանույթը:"</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Չհաջողվեց պահել էկրանի պատկերը սահմանափակ հիշողության պատճառով:"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Այս հավելվածը կամ ձեր կազմակերպությունը չի թույլատրում Էկրանի պատկերի ստացումը:"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB ֆայլերի փոխանցման ընտրանքներ"</string>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings_tv.xml b/packages/SystemUI/res/values-hy-rAM/strings_tv.xml
index 2eed586..0ddb715 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings_tv.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Փակել PIP-ն"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Լիէկրան"</string>
     <string name="pip_play" msgid="674145557658227044">"Նվագարկել"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Դադարեցնել"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"PIP-ն կառավարելու համար սեղմած պահեք "<b>"HOME"</b>" կոճակը"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP-ն կառավարելու համար սեղմեք և պահեք HOME\n կոճակը"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Պարզ է"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 9eb1331..7723663 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -73,6 +73,7 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Tangkapan layar diambil."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Sentuh untuk melihat tangkapan layar Anda."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Tidak dapat mengambil tangkapan layar."</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Terjadi masalah saat menyimpan tangkapan layar."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Tidak dapat menyimpan tangkapan layar karena ruang penyimpanan terbatas."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Mengambil tangkapan layar tidak diizinkan oleh aplikasi atau organisasi."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opsi transfer file USB"</string>
@@ -220,10 +221,8 @@
     <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Mode kerja aktif."</string>
     <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Mode kerja dinonaktifkan."</string>
     <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Mode kerja diaktifkan."</string>
-    <!-- no translation found for accessibility_quick_settings_data_saver_changed_off (650231949881093289) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_data_saver_changed_on (4218725402373934151) -->
-    <skip />
+    <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Penghemat Data nonaktif."</string>
+    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Penghemat Data diaktifkan."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"Kecerahan tampilan"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Data 2G-3G dijeda"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Data 4G dijeda"</string>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index 1932595..6b4f191 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Skjámynd var tekin."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Snertu til að skoða skjámyndina."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Ekki tókst að taka skjámynd."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Ekki tókst að vista skjámynd vegna takmarkaðs geymslupláss."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Forritið eða fyrirtækið þitt leyfir ekki að teknar séu skjámyndir."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Valkostir USB-skráaflutnings"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 34faece..6fc814a 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot acquisito."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Tocca per visualizzare il tuo screenshot."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Impossibile acquisire lo screenshot."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Impossibile salvare lo screenshot a causa dello spazio di archiviazione limitato."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"L\'acquisizione di screenshot non è consentita dall\'app o dall\'organizzazione."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opzioni trasferimento file USB"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 9beed4f..2eda0e4 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -75,6 +75,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"צילום המסך בוצע."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"גע כדי להציג את צילום המסך שלך"</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"לא ניתן לבצע צילום מסך."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"לא ניתן לשמור צילום מסך עקב שטח אחסון מוגבל."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"האפליקציה, או הארגון שלך, אינם מתירים לבצע צילומי מסך."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"‏אפשרויות העברת קבצים ב-USB"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index b4b24ec..27bb232 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -73,6 +73,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_to_save_unknown_text" msgid="7887826345701753830">"スクリーンショットの保存中に問題が発生しました。"</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"空き容量が足りないため、スクリーンショットを保存できません。"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"アプリまたは組織によって許可されていないため、スクリーンショットは撮れません。"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USBファイル転送オプション"</string>
diff --git a/packages/SystemUI/res/values-ja/strings_tv.xml b/packages/SystemUI/res/values-ja/strings_tv.xml
index 8c56866..be6693b 100644
--- a/packages/SystemUI/res/values-ja/strings_tv.xml
+++ b/packages/SystemUI/res/values-ja/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"PIP を閉じる"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"全画面表示"</string>
     <string name="pip_play" msgid="674145557658227044">"再生"</string>
     <string name="pip_pause" msgid="8412075640017218862">"一時停止"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"PIP を管理するには ["<b>"ホーム"</b>"] を押し続けます"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP を管理するには\n[ホーム] ボタンを押し続けます"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"閉じる"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 4c461de..41da191 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"სკრინშოტი გადაღებულია."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"შეეხეთ ეკრანის სურათის სანახავად."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"ვერ მოხერხდა ეკრანის ანაბეჭდის გადაღება."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"ეკრანის ანაბეჭდის შენახვა ვერ მოხერხდა შეზღუდული მეხსიერების გამო."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ეკრანის ანაბეჭდების შექმნა არ არის ნებადართული აპის ან თქვენი ორგანიზაციის მიერ."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB ფაილის ტრანსფერის პარამეტრები"</string>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings_tv.xml b/packages/SystemUI/res/values-ka-rGE/strings_tv.xml
index 9c5b0d6..97944c3 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings_tv.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"PIP-ის დახურვა"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"სრულ ეკრანზე"</string>
     <string name="pip_play" msgid="674145557658227044">"დაკვრა"</string>
     <string name="pip_pause" msgid="8412075640017218862">"პაუზა"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"PIP-ის სამართავად, გეჭიროთ "<b>"მთავარ ღილაკზე"</b></string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP-ის სამართავად, ხანგრძლივად\nდააჭირეთ მთავარ ღილაკს"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"გასაგებია"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index f1c09d8..bc56c8e 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -73,6 +73,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_to_save_unknown_text" msgid="7887826345701753830">"Скриншотты сақтау кезінде мәселе орын алды."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Жадтағы шектеулі бос орынға байланысты скриншотты сақтау мүмкін емес."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Қолданба немесе ұйым скриншоттар түсіруге рұқсат етпейді."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB файлын жіберу опциялары"</string>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml b/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml
index 3fc3403..f67157c 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"PIP жабу"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Толық экран"</string>
     <string name="pip_play" msgid="674145557658227044">"Ойнату"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Кідірту"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"PIP бас. үшін "<b>"HOME"</b>" түй. ұс. тұр."</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP бас. үшін HOME\n түй. бас., ұс. тұр."</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Түсіндім"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 845a48e..cafa329 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -73,6 +73,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_to_save_unknown_text" msgid="7887826345701753830">"បានជួបប្រទះបញ្ហាខណៈពេលរក្សាទុកការថតអេក្រង់"</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"មិនអាចរក្សាទុករូបថតអេក្រង់បានទេដោយសារទំហំផ្ទុកមានកម្រិត។"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ការថតរូបអេក្រង់មិនត្រូវបានអនុញ្ញាតដោយកម្មវិធីនេះ ឬស្ថាប័នរបស់អ្នក។"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"ជម្រើស​ផ្ទេរ​ឯកសារ​តាម​យូអេសប៊ី"</string>
diff --git a/packages/SystemUI/res/values-km-rKH/strings_tv.xml b/packages/SystemUI/res/values-km-rKH/strings_tv.xml
index 4b42132..cc0a8b0 100644
--- a/packages/SystemUI/res/values-km-rKH/strings_tv.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"បិទ PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"ពេញអេក្រង់"</string>
     <string name="pip_play" msgid="674145557658227044">"ចាក់"</string>
     <string name="pip_pause" msgid="8412075640017218862">"ផ្អាក"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"សង្កត់ប៊ូតុង "<b>"ដើម"</b>" ដើម្បីគ្រប់គ្រង PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"ចុច និងសង្កត់ប៊ូតុង ដើម\nដើម្បីគ្រប់គ្រង PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"យល់ហើយ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index bf604e7..62a1235 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಸೆರೆಹಿಡಿಯಲಾಗಿದೆ."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ವೀಕ್ಷಿಸಲು ಸ್ಪರ್ಶಿಸಿ."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಸೆರೆಹಿಡಿಯಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"ಪರಿಮಿತ ಸಂಗ್ರಹಣೆ ಸ್ಥಳದ ಕಾರಣದಿಂದಾಗಿ ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಉಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳುವುದನ್ನು ಅಪ್ಲಿಕೇಶನ್ ಅಥವಾ ನಿಮ್ಮ ಸಂಸ್ಥೆ ಅನುಮತಿಸುವುದಿಲ್ಲ."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB ಫೈಲ್ ವರ್ಗಾವಣೆ ಆಯ್ಕೆಗಳು"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 1a1cabe..fca1dba 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"캡쳐화면 저장됨"</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"캡쳐화면을 보려면 터치하세요."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"캡쳐화면을 캡쳐하지 못했습니다."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"저장용량이 부족하여 스크린샷을 저장할 수 없습니다."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"앱이나 조직에서 스크린샷 촬영을 허용하지 않습니다."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB 파일 전송 옵션"</string>
diff --git a/packages/SystemUI/res/values-ko/strings_tv.xml b/packages/SystemUI/res/values-ko/strings_tv.xml
index e7cac9f..ea12d5e 100644
--- a/packages/SystemUI/res/values-ko/strings_tv.xml
+++ b/packages/SystemUI/res/values-ko/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"PIP 닫기"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"전체화면"</string>
     <string name="pip_play" msgid="674145557658227044">"재생"</string>
     <string name="pip_pause" msgid="8412075640017218862">"일시중지"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109"><b>"HOME"</b>"을 눌러 PIP 제어"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"HOME\n버튼을 길게 눌러 PIP 제어"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"확인"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index 571b691..8894820 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Скриншот тартылды."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Тийип, скриншотту көрүңүз."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Скриншот кылынбай жатат."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Сактагычта бош орун аз болгондуктан скриншот сакталбай жатат."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Скриншот тартууга колдонмо же ишканаңыз уруксат бербейт."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB менен файл өткөрүү мүмкүнчүлүктөрү"</string>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings_tv.xml b/packages/SystemUI/res/values-ky-rKG/strings_tv.xml
index 2724230..e95bc89 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings_tv.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"PIP\'ти жабуу"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Толук экран"</string>
     <string name="pip_play" msgid="674145557658227044">"Ойнотуу"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Тындыруу"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"PIP\'ти көзөмөлдөө үчүн "<b>"БАШКЫ БЕТ"</b>" баскычын кармап туруңуз"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP\'ти көзөмөлдөө үчүн БАШКЫ БЕТ\nбаскычын басып, кармап туруңуз"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Түшүндүм"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index 823e02b..80c1e01 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -73,6 +73,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_to_save_unknown_text" msgid="7887826345701753830">"ເກີດບັນຫາໃນການບັນທຶກພາບໜ້າຈໍຂອງທ່ານ."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"ບໍ່ສາມາດຖ່າຍຮູບໜ້າຈໍໄດ້ເນື່ອງຈາກພື້ນທີ່ຈັດເກັບຂໍ້ມູນມີຈຳກັດ."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ແອັບ ຫຼື ອົງກອນຂອງທ່ານບໍ່ອະນຸຍາດໃຫ້ມີການຖ່າຍຮູບໜ້າຈໍ."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB ໂຕເລືອກການຍ້າຍໄຟລ໌"</string>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings_tv.xml b/packages/SystemUI/res/values-lo-rLA/strings_tv.xml
index 47374e8..f6bc833 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings_tv.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"ປິດ PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"ເຕັມໜ້າຈໍ"</string>
     <string name="pip_play" msgid="674145557658227044">"ຫຼິ້ນ"</string>
     <string name="pip_pause" msgid="8412075640017218862">"ຢຸດຊົ່ວຄາວ"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"ກົດ "<b>"HOME"</b>" ຄ້າງໄວ້ເພື່ອຄວບຄຸມ PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"ກົດປຸ່ມ HOME\nຄ້າງໄວ້ເພື່ອຄວບຄຸມ PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"ເຂົ້າໃຈແລ້ວ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index db354eb..4299efa 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -75,6 +75,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Ekrano kopija užfiksuota."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Palieskite, kad peržiūrėtumėte ekrano kopiją."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Nepavyko užfiksuoti ekrano kopijos."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Negalima išsaugoti ekrano kopijos dėl ribotos saugyklos vietos."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Jūsų organizacijoje arba naudojant šią programą neleidžiama daryti ekrano kopijų"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB failo perdavimo parinktys"</string>
diff --git a/packages/SystemUI/res/values-lt/strings_tv.xml b/packages/SystemUI/res/values-lt/strings_tv.xml
index ac3a44e..140b55d 100644
--- a/packages/SystemUI/res/values-lt/strings_tv.xml
+++ b/packages/SystemUI/res/values-lt/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Uždaryti PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Visas ekranas"</string>
     <string name="pip_play" msgid="674145557658227044">"Leisti"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Pristabdyti"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Kad vald. PIP, pal. pasp. m. "<b>"PAGRINDINIS"</b></string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Kad vald. PIP, pal.\npasp. m. PAGRINDINIS"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Supratau"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 29e1b95..ad00ad0 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -74,6 +74,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Ekrānuzņēmums ir uzņemts."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Pieskarieties, lai skatītu ekrānuzņēmumu."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Nevarēja uzņemt ekrānuzņēmumu."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Nevar saglabāt ekrānuzņēmumu, jo krātuvē nepietiek vietas."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Lietotne vai jūsu organizācija neatļauj veikt ekrānuzņēmumus."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB failu pārsūtīšanas opcijas"</string>
diff --git a/packages/SystemUI/res/values-lv/strings_tv.xml b/packages/SystemUI/res/values-lv/strings_tv.xml
index 7fa804d..d7ca370 100644
--- a/packages/SystemUI/res/values-lv/strings_tv.xml
+++ b/packages/SystemUI/res/values-lv/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Aizvērt PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Pilnekrāna režīms"</string>
     <string name="pip_play" msgid="674145557658227044">"Atskaņot"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Apturēt"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Turiet taustiņu "<b>"SĀKUMS"</b>", lai kontrolētu PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Nospiediet un turiet pogu SĀKUMS,\n lai kontrolētu PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Labi"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index cf97df8..4116b6f 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Сликата на екранот е снимена."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Допрете за да ја видите сликата на екранот."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Сликата на екранот не можеше да се сними."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Сликата од екранот не може да се зачува поради ограничена меморија."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Апликацијата или вашата организација не дозволува создавање слики од екранот."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Пренос на датотека со УСБ"</string>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings_tv.xml b/packages/SystemUI/res/values-mk-rMK/strings_tv.xml
index 30c6db9..5f88cb5 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings_tv.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Затвори PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Цел екран"</string>
     <string name="pip_play" msgid="674145557658227044">"Пушти"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Пауза"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Задржете "<b>"ДОМА"</b>" за кон. PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Притиснете и задржете го копчето\nДОМА за контролирање PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Разбрав"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index df69933..f861a00 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"സ്‌ക്രീൻഷോട്ട് എടുത്തു."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"നിങ്ങളുടെ സ്‌ക്രീൻഷോട്ട് കാണാനായി സ്‌പർശിക്കുക."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"സ്‌ക്രീൻഷോട്ട് എടുക്കാൻ കഴിഞ്ഞില്ല."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"സ്റ്റോറേജ് ഇടം പരിമിതമായതിനാൽ സ്ക്രീൻഷോട്ട് സംരക്ഷിക്കാൻ കഴിയില്ല."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"സ്ക്രീൻഷോട്ടുകൾ എടുക്കുന്നത് ആപ്പോ നിങ്ങളുടെ സ്ഥാപനമോ അനുവദിക്കുന്നില്ല."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB ഫയൽ കൈമാറൽ ഓപ്‌ഷനുകൾ"</string>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings_tv.xml b/packages/SystemUI/res/values-ml-rIN/strings_tv.xml
index 564a32a..0094bb6 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings_tv.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"PIP അടയ്ക്കുക"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"പൂര്‍ണ്ണ സ്ക്രീന്‍"</string>
     <string name="pip_play" msgid="674145557658227044">"പ്ലേ ചെയ്യുക"</string>
     <string name="pip_pause" msgid="8412075640017218862">"തൽക്കാലം നിർത്തൂ"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"PIP നിയന്ത്രിക്കാൻ "<b>"ഹോം"</b>" പിടിക്കുക"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP നിയന്ത്രിക്കാൻ ഹോം\nബട്ടൺ അമർത്തിപ്പിടിക്കുക"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"മനസ്സിലായി"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 793e165..73df535 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -71,6 +71,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_to_save_unknown_text" msgid="7887826345701753830">"Дэлгэцийн агшинг хадгалахад алдаа гарлаа."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Хадгалах сангийн багтаамж бага байгаа тул дэлгэцийн авсан зургийг хадгалах боломжгүй байна."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Дэлгэцийн зураг авахыг апп эсвэл танай байгууллагаас зөвшөөрөөгүй байна."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB файл шилжүүлэх сонголт"</string>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings_tv.xml b/packages/SystemUI/res/values-mn-rMN/strings_tv.xml
index ae4029f..78b7cc8 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings_tv.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"PIP-г хаах"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Бүтэн дэлгэц"</string>
     <string name="pip_play" msgid="674145557658227044">"Тоглуулах"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Түр зогсоох"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"PIP-г удирдахын тулд "<b>"HOME"</b>" товчлуурыг дарна уу"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP-г удирдахын тулд HOME\nтовчлуурыг дараад хүлээнэ үү"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Ойлголоо"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index e39db5d..a3cb736 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"स्क्रीनशॉट कॅप्चर केला."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"आपला स्क्रीनशॉट पाहण्यासाठी स्पर्श करा."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"स्क्रीनशॉट कॅप्चर करू शकलो नाही."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"मर्यादित संचय जागेमुळे स्क्रीनशॉट जतन करू शकत नाही."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"अॅप किंवा आपल्या संस्थेद्वारे स्क्रीनशॉट घेण्यास अनुमती नाही."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB फाईल स्थानांतरण पर्याय"</string>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 3ec3db1..75fdf62 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Tangkapan skrin ditangkap."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Sentuh untuk melihat tangkapan skrin anda."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Tidak dapat menangkap tangkapan skrin."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Tidak dapat menyimpan tangkapan skrin kerana ruang storan terhad."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Apl atau organisasi anda tidak membenarkan pengambilan tangkapan skrin."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Pilihan pemindahan fail USB"</string>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings_tv.xml b/packages/SystemUI/res/values-ms-rMY/strings_tv.xml
index feae042..5fc98b9 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings_tv.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Tutup PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Skrin penuh"</string>
     <string name="pip_play" msgid="674145557658227044">"Main"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Jeda"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Thn "<b>"SKRN UTMA"</b>" utk kwl PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Tkn &amp; thn butang SKRIN UTAMA\nutk mengawal PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index ca34144..d7597a5 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -73,6 +73,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_to_save_unknown_text" msgid="7887826345701753830">"ဖန်သားပြင်ဓာတ်ပုံဖမ်းယူမှုကို သိမ်းဆည်းရာတွင် ပြဿနာကြုံခဲ့သည်။"</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"သိုလှောင်ခန်းနေရာ အကန့်အသတ်ရှိသောကြောင့် ဖန်သားပြင်ဓာတ်ပုံကို သိမ်းဆည်း၍မရပါ။"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ဖန်သားပြင်ဓာတ်ပုံရိုက်ကူးခြင်းကို အက်ပ်မှ သို့မဟုတ် သင့်အဖွဲ့အစည်းမှ ခွင့်မပြုပါ။"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB ဖိုင်ပြောင်း ရွေးမှုများ"</string>
diff --git a/packages/SystemUI/res/values-my-rMM/strings_tv.xml b/packages/SystemUI/res/values-my-rMM/strings_tv.xml
index ebadebe..8491e37 100644
--- a/packages/SystemUI/res/values-my-rMM/strings_tv.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings_tv.xml
@@ -23,7 +23,7 @@
     <string name="pip_fullscreen" msgid="8604643018538487816">"မျက်နှာပြင် အပြည့်"</string>
     <string name="pip_play" msgid="674145557658227044">"ဖွင့်ပါ"</string>
     <string name="pip_pause" msgid="8412075640017218862">"ဆိုင်းငံ့ပါ"</string>
-    <string name="pip_hold_home" msgid="340086535668778109">"PIP ကိုထိန်းချုပ်ရန် "<b>"ပင်မခလုတ်"</b>" ကိုဖိထားပါ"</string>
-    <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP ကိုထိန်းချုပ်ရန် ပင်မခလုတ်\nကိုနှိပ်ပြီးဖိထားပါ"</string>
+    <string name="pip_hold_home" msgid="340086535668778109">"PIP ကိုထိန်းချုပ်ရန် "<b>"ပင်မ"</b>" ခလုတ်ကို ဖိထားပါ"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP ကိုထိန်းချုပ်ရန် ပင်မ\nခလုတ်ကို နှိပ်ပြီးဖိထားပါ"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"ရပါပြီ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 269746e..5b0c6eb 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Skjermdumpen er lagret."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Trykk for å se skjermdumpen."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Kan ikke lagre skjermdumpen."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Kan ikke lagre skjermdumpen på grunn av begrenset lagringsplass."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Appen eller organisasjonen din tillater ikke at du tar skjermdumper."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Altern. for USB-filoverføring"</string>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 882a194..42067ab 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -73,6 +73,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_to_save_unknown_text" msgid="7887826345701753830">"स्क्रिनसटलाई सुरक्षित गर्दा समस्या भयो।"</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"सीमित भण्डारण स्थान उपलब्ध रहेको हुनाले स्क्रिनसटलाई सुरक्षित गर्न सकिँदैन।"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"अनुप्रयोग वा तपाईँको संगठनले स्क्रिनसट लिन अनुमति दॅिंदैन।"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB फाइल सार्ने विकल्पहरू"</string>
@@ -220,10 +221,8 @@
     <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"कार्य मोड अन।"</string>
     <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"कार्य मोड बन्द भयो।"</string>
     <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"कार्य मोड सक्रिय भयो।"</string>
-    <!-- no translation found for accessibility_quick_settings_data_saver_changed_off (650231949881093289) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_data_saver_changed_on (4218725402373934151) -->
-    <skip />
+    <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"डेटा सेभरलाई निष्क्रिय पारियो।"</string>
+    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"डेटा सेभरलाई सक्रिय गरियो।"</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"प्रदर्शन चमक"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G डेटा रोकिएको छ"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G डेटा रोकिएको छ"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 99acbaa..6f15baf 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -73,6 +73,7 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot gemaakt."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Raak aan om je screenshot te bekijken."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Screenshot is niet gemaakt."</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Er is een probleem opgetreden bij het opslaan van het screenshot."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Kan screenshot niet opslaan vanwege beperkte opslagruimte."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Het maken van screenshots wordt niet toegestaan door de app of je organisatie."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opties voor USB-bestandsoverdracht"</string>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index 2de6583..d07c4d2 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -73,6 +73,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_to_save_unknown_text" msgid="7887826345701753830">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਰੱਖਿਅਤ ਕਰਨ ਦੌਰਾਨ ਸਮੱਸਿਆ ਆਈ।"</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"ਸੀਮਿਤ ਸਟੋਰੇਜ ਥਾਂ ਦੇ ਕਾਰਨ ਸਕ੍ਰੀਨਸ਼ਾਟ ਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤਾ ਸਕਦਾ।"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ਐਪ ਜਾਂ ਤੁਹਾਡੀ ਸੰਸਥਾ ਦੁਆਰਾ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲੈਣ ਦੀ ਮਨਜ਼ੂਰੀ ਨਹੀਂ ਹੈ।"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ ਚੋਣਾਂ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 0fdb4df..8a1fff6 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -75,6 +75,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Wykonano zrzut ekranu."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Dotknij, aby wyświetlić zrzut ekranu."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Nie udało się wykonać zrzutu ekranu."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Nie można zapisać zrzutu ekranu, bo brakuje miejsca w pamięci."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Nie możesz wykonać zrzutu ekranu, bo nie zezwala na to aplikacja lub Twoja organizacja."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB – opcje przesyłania plików"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 86b94ab..1cf0ed9 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Captura de tela obtida."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Toque para visualizar a captura de tela."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Não foi possível obter a captura de tela."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Não é possível salvar a captura de tela, porque não há espaço suficiente."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Capturas de tela não são permitidas pelo app ou por sua organização."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opções transf. arq. por USB"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
index 742ea28..21d36e0 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Fechar PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Tela cheia"</string>
     <string name="pip_play" msgid="674145557658227044">"Reproduzir"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Pausar"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Mantenha "<b>"INÍCIO"</b>" pressionado para controlar o PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Mantenha o botão INÍCIO\npressionado para controlar o PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Entendi"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 35ef0dd..520abc4 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -73,6 +73,7 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Captura de ecrã efetuada"</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Toque para ver a captura de ecrã"</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Não foi possível obter captura de ecrã."</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Problema encontrado ao guardar a captura de ecrã."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Não é possível guardar a captura de ecrã devido a espaço de armazenamento limitado."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"A aplicação ou a sua entidade não tem autorização para tirar capturas de ecrã."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opções de transm. de fich. USB"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 86b94ab..1cf0ed9 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Captura de tela obtida."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Toque para visualizar a captura de tela."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Não foi possível obter a captura de tela."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Não é possível salvar a captura de tela, porque não há espaço suficiente."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Capturas de tela não são permitidas pelo app ou por sua organização."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opções transf. arq. por USB"</string>
diff --git a/packages/SystemUI/res/values-pt/strings_tv.xml b/packages/SystemUI/res/values-pt/strings_tv.xml
index 742ea28..21d36e0 100644
--- a/packages/SystemUI/res/values-pt/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Fechar PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Tela cheia"</string>
     <string name="pip_play" msgid="674145557658227044">"Reproduzir"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Pausar"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Mantenha "<b>"INÍCIO"</b>" pressionado para controlar o PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Mantenha o botão INÍCIO\npressionado para controlar o PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Entendi"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index b854ffb..113f2bc 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -74,6 +74,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Captură de ecran realizată."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Atingeți pentru a vedea captura de ecran."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Captura de ecran nu a putut fi realizată."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Captura de ecran nu poate fi salvată din cauza spațiului de stocare limitat."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Crearea capturilor de ecran nu este permisă de aplicație sau de organizația dvs."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opțiuni pentru transferul de fișiere prin USB"</string>
diff --git a/packages/SystemUI/res/values-ro/strings_tv.xml b/packages/SystemUI/res/values-ro/strings_tv.xml
index cbe5e38..e30b2f9 100644
--- a/packages/SystemUI/res/values-ro/strings_tv.xml
+++ b/packages/SystemUI/res/values-ro/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Închideți PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Ecran complet"</string>
     <string name="pip_play" msgid="674145557658227044">"Redați"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Întrerupeți"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Apăsați lung "<b>"ACASĂ"</b>" pentru a controla PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Apăsați lung ACASĂ\npentru a controla PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Am înțeles"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 5a7e51c..c131284 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -75,6 +75,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Скриншот сохранен"</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Нажмите, чтобы просмотреть"</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Не удалось сохранить скриншот."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Не удалось сохранить скриншот: недостаточно места."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Не удалось сделать скриншот: нет разрешения от приложения или организации."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Параметры передачи через USB"</string>
diff --git a/packages/SystemUI/res/values-ru/strings_tv.xml b/packages/SystemUI/res/values-ru/strings_tv.xml
index dd9cb5a..f25b460 100644
--- a/packages/SystemUI/res/values-ru/strings_tv.xml
+++ b/packages/SystemUI/res/values-ru/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"\"Кадр в кадре\" – выйти"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Во весь экран"</string>
     <string name="pip_play" msgid="674145557658227044">"Воспроизвести"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Приостановить"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Управляйте кадром в кадре, удерживая кнопку "<b>"ГЛАВНАЯ"</b></string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Управляйте кадром в кадре,\nудерживая кнопку \"ГЛАВНАЯ\""</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"ОК"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index 1e178cf..5a09d3e 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -73,6 +73,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_to_save_unknown_text" msgid="7887826345701753830">"තිර රුව සුරකින අතරතුර ගැටලුවක් ඇති විය."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"සීමිත ගබඩා ඉඩ නිසා තිර රුව සුරැකිය නොහැකිය."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"තිර රූ ගැනීමට යෙදුම හෝ ඔබගේ සංවිධානය ඉඩ නොදේ."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB ගොනු හුවමාරු විකල්ප"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index c075980..26d6d2f 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -75,6 +75,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Snímka obrazovky bola zaznamenaná."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Snímku obrazovky zobrazíte dotykom."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Snímku obrazovky sa nepodarilo zachytiť."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Snímku obrazovky nie je možné vytvoriť z dôvodu nedostatku miesta v úložisku."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Vytváranie snímok obrazovky je zakázané aplikáciou alebo vašou organizáciou."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Možnosti prenosu súborov USB"</string>
@@ -222,10 +224,8 @@
     <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Pracovný režim – zap."</string>
     <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Pracovný režim je vypnutý."</string>
     <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Pracovný režim je zapnutý."</string>
-    <!-- no translation found for accessibility_quick_settings_data_saver_changed_off (650231949881093289) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_data_saver_changed_on (4218725402373934151) -->
-    <skip />
+    <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Šetrič dát bol vypnutý."</string>
+    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Šetrič dát bol zapnutý."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"Jas displeja"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Dátové prenosy 2G a 3G sú pozastavené"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Dátové prenosy 4G sú pozastavené"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 8aa79be..b268f18 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -75,6 +75,7 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Posnetek zaslona je shranjen."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Dotaknite se, če si želite ogledati posnetek zaslona."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Posnetka zaslona ni bilo mogoče shraniti."</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Pri shranjevanju posnetka zaslona je prišlo do težave."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Shranjevanje posnetka zaslona ni mogoče zaradi omejenega prostora za shranjevanje."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Aplikacija ali organizacija ne dovoljuje posnetkov zaslona."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Možnosti prenosa datotek prek USB-ja"</string>
diff --git a/packages/SystemUI/res/values-sl/strings_tv.xml b/packages/SystemUI/res/values-sl/strings_tv.xml
index 9fab6e1..e1d1604 100644
--- a/packages/SystemUI/res/values-sl/strings_tv.xml
+++ b/packages/SystemUI/res/values-sl/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Zapri način PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Celozaslonsko"</string>
     <string name="pip_play" msgid="674145557658227044">"Predvajanje"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Zaustavitev"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Pridr. "<b>"HOME"</b>" za up. n. PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Pridržite gumb HOME\nza upravljanje načina PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Razumem"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml
index 8314044..b3e6ea8 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Pamja e ekranit u kap."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Prek për të parë pamjen e ekranit tënd."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Nuk mundi të kapte pamjen e ekranit."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Pamja e ekranit nuk mund të ruhet për shkak të hapësirës ruajtëse të kufizuar."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Nxjerrja e pamjeve të ekranit nuk lejohet nga aplikacioni ose organizata jote."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opsionet e transferimit të dosjeve të USB-së"</string>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings_tv.xml b/packages/SystemUI/res/values-sq-rAL/strings_tv.xml
index 10cf2f9..28bfbb5 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings_tv.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Mbyll PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Ekrani i plotë"</string>
     <string name="pip_play" msgid="674145557658227044">"Luaj"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Pauzë"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Mbaj shtypur "<b>"HOME"</b>" për të kontrolluar PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Shtyp dhe mbaj shtypur butonin HOME\npër të kontrolluar PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"E kuptova"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 318a92a..9c26ebd 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -74,6 +74,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Снимак екрана је направљен."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Додирните да бисте видели снимак екрана."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Није могуће направити снимак екрана."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Чување снимка екрана није успело због ограниченог меморијског простора."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Апликација или организација не дозвољавају прављење снимака екрана."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Опције USB преноса датотека"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index a50e744..0fb5731 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Skärmdumpen har tagits."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Tryck här om du vill visa skärmdumpen."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Det gick inte att ta någon skärmdump."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Det går inte att spara skärmdumpen eftersom lagringsutrymmet inte räcker."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Appen eller organisationen tillåter inte att du tar skärmdumpar."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Överföringsalternativ"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 2a10259b..a716281 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Picha ya skrini imenaswa."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Gusa ili kuona picha yako ya skrini."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Haikuweza kunasa picha ya skrini"</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Haina nafasi ya kutosha kuhifadhi picha ya skrini."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Shirika au programu yako haikuruhusu upige picha za skrini."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Machaguo ya uhamisho wa faili la USB"</string>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index eb7dbe4..59fe9dd 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"ஸ்கிரீன் ஷாட் எடுக்கப்பட்டது."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"உங்கள் ஸ்க்ரீன் ஷாட்டைப் பார்க்க தொடவும்."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"ஸ்க்ரீன் ஷாட்டை எடுக்க முடியவில்லை."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"போதுமான சேமிப்பிடம் இல்லாததால் ஸ்கிரீன்ஷாட்டைச் சேமிக்க முடியவில்லை."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"பயன்பாடு அல்லது உங்கள் நிறுவனம் ஸ்கிரீன்ஷாட்டுகளை எடுக்க அனுமதிக்கவில்லை."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB கோப்பு இடமாற்ற விருப்பங்கள்"</string>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index 29e2539..c7f9b42 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"స్క్రీన్‌షాట్ క్యాప్చర్ చేయబడింది."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"మీ స్క్రీన్‌షాట్‌ను వీక్షించడానికి తాకండి."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"స్క్రీన్‌షాట్‌ను క్యాప్చర్ చేయడం సాధ్యపడలేదు."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"పరిమిత నిల్వ స్థలం కారణంగా స్క్రీన్‌షాట్‌ను సేవ్ చేయడం సాధ్యపడదు."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"స్క్రీన్‌షాట్‌లు తీయడానికి అనువర్తనం లేదా మీ సంస్థ అనుమతించలేదు."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB ఫైల్ బదిలీ ఎంపికలు"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 2fb82b7..98029ed 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -73,6 +73,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_to_save_unknown_text" msgid="7887826345701753830">"พบปัญหาขณะกำลังบันทึกภาพหน้าจอ"</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"ไม่สามารถบันทึกภาพหน้าจอเนื่องจากพื้นที่เก็บข้อมูลมีจำกัด"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"แอปหรือองค์กรของคุณไม่อนุญาตให้จับภาพหน้าจอ"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"ตัวเลือกการถ่ายโอนไฟล์ USB"</string>
diff --git a/packages/SystemUI/res/values-th/strings_tv.xml b/packages/SystemUI/res/values-th/strings_tv.xml
index 78fd1b8..f1c24ec 100644
--- a/packages/SystemUI/res/values-th/strings_tv.xml
+++ b/packages/SystemUI/res/values-th/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"ปิด PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"เต็มหน้าจอ"</string>
     <string name="pip_play" msgid="674145557658227044">"เล่น"</string>
     <string name="pip_pause" msgid="8412075640017218862">"หยุดชั่วคราว"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"กด "<b>"HOME"</b>" ค้างไว้เพื่อควบคุม PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"กดปุ่ม HOME ค้างไว้\nเพื่อควบคุม PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"รับทราบ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 943d21f..d93fd96 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -73,6 +73,7 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Nakuha ang screenshot."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Pindutin upang tingnan ang iyong screenshot."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Hindi makuha ang screenshot."</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Nagkaroon ng problema habang sine-save ang screenshot."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Hindi ma-save ang screenshot dahil sa limitadong espasyo ng storage."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Hindi pinapayagan ng app o ng iyong organisasyon ang pagkuha ng mga screenshot."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opsyon paglipat ng USB file"</string>
diff --git a/packages/SystemUI/res/values-tl/strings_tv.xml b/packages/SystemUI/res/values-tl/strings_tv.xml
index db898c6..85a4f5b 100644
--- a/packages/SystemUI/res/values-tl/strings_tv.xml
+++ b/packages/SystemUI/res/values-tl/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Isara ang PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Full screen"</string>
     <string name="pip_play" msgid="674145557658227044">"I-play"</string>
     <string name="pip_pause" msgid="8412075640017218862">"I-pause"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"I-hold ang "<b>"HOME"</b>" para makontrol ang PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"I-hold ang button na HOME\nupang makontrol ang PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index a294977..12be4c3 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Ekran görüntüsü alındı."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Ekran görüntünüzü izlemek için dokunun."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Ekran görüntüsü alınamadı."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Depolama alanı sınırlı olduğundan ekran görüntüsü kaydedilemiyor."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Uygulama veya kuruluşunuz, ekran görüntüsü alınmasına izin vermiyor."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB dosya aktarım seçenekleri"</string>
diff --git a/packages/SystemUI/res/values-tr/strings_tv.xml b/packages/SystemUI/res/values-tr/strings_tv.xml
index 255df49..ea136b1 100644
--- a/packages/SystemUI/res/values-tr/strings_tv.xml
+++ b/packages/SystemUI/res/values-tr/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"PIP\'yi kapat"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Tam ekran"</string>
     <string name="pip_play" msgid="674145557658227044">"Oynat"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Duraklat"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"PIP\'yi kontrol etmek için "<b>"ANA EKRAN"</b>"\'ı basılı tutun"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP\'yi kontrol etmek için\nANA EKRAN düğmesini basılı tutun"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"Anladım"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 41b89f9..e7721f1 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -75,6 +75,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Знімок екрана зроблено."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Торкніться, щоб переглянути знімок екрана."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Не вдалося зробити знімок екрана."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Не вдалося зберегти знімок екрана через обмежений обсяг пам’яті."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Додаток або ваша організація не дозволяють робити знімки екрана."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Парам.передав.файлів через USB"</string>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index ba2d014..dd76828 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"اسکرین شاٹ کیپچر کیا گیا۔"</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"اپنے اسکرین شاٹ دیکھنے کیلئے چھوئیں۔"</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"اسکرین شاٹ کیپچر نہیں کر سکے۔"</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"محدود اسٹوریج جگہ کی وجہ سے اسکرین شاٹس نہیں لئے جا سکتے۔"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ایپ یا آپ کی تنظیم کی جانب سے اسکرین شاٹس لینے کی اجازت نہیں ہے۔"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"‏USB فائل منتقل کرنیکے اختیارات"</string>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings_tv.xml b/packages/SystemUI/res/values-ur-rPK/strings_tv.xml
index 28987c3..4929f81 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings_tv.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"‏PIP بند کریں"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"فُل اسکرین"</string>
     <string name="pip_play" msgid="674145557658227044">"چلائیں"</string>
     <string name="pip_pause" msgid="8412075640017218862">"موقوف کریں"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"‏PIP کنٹرول کرنے کیلئے "<b>"ہوم"</b>" پکڑے رکھیں"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"‏PIP کنٹرول کرنے کیلئے\nہوم بٹن دبائیں اور پکڑے رکھیں"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"سمجھ آ گئی"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index 0ad7df6..21400b3 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Skrinshot saqlandi."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Ko‘rish uchun bu yerga bosing."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Skrinshot saqlanmadi."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Xotirada joy kamligi uchun skrinshotni saqlab bo‘lmadi."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Ilova yoki tashkilotingiz skrinshot olishni taqiqlagan."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB fayl ko‘chirish moslamalari"</string>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml b/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml
index 00d25960..d6ffb67 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"PIP’ni yopish"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"To‘liq ekran"</string>
     <string name="pip_play" msgid="674145557658227044">"Ijro"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Pauza"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109"><b>"BOSHIGA"</b>" tugmasini bosib turib, PIP’ni boshqaring"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"BOSHIGA tugmasini bosib turib,\nPIP’ni boshqaring"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 9a80cb2..8f947af 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -73,6 +73,7 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Đã chụp ảnh màn hình."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Chạm để xem ảnh chụp màn hình của bạn."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Không thể chụp ảnh màn hình."</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Đã gặp phải sự cố khi đang lưu ảnh chụp màn hình."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Không thể lưu ảnh chụp màn hình do giới hạn dung lượng bộ nhớ."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Ứng dụng hoặc tổ chức của bạn không cho phép chụp ảnh màn hình."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Tùy chọn truyền tệp USB"</string>
diff --git a/packages/SystemUI/res/values-vi/strings_tv.xml b/packages/SystemUI/res/values-vi/strings_tv.xml
index e4cbc48..48ba444 100644
--- a/packages/SystemUI/res/values-vi/strings_tv.xml
+++ b/packages/SystemUI/res/values-vi/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"Đóng PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Toàn màn hình"</string>
     <string name="pip_play" msgid="674145557658227044">"Phát"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Tạm dừng"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"Giữ "<b>"HOME"</b>" để đ.khiển PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"Nhấn và giữ nút HOME\nđể điều khiển PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 7f7108c..74d787f 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"已抓取屏幕截图。"</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"触摸可查看您的屏幕截图。"</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"无法抓取屏幕截图。"</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"由于存储空间有限,无法保存屏幕截图。"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"此应用或贵单位不允许进行屏幕截图。"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB文件传输选项"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
index 2abd338..860df35 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"关闭 PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"全屏"</string>
     <string name="pip_play" msgid="674145557658227044">"播放"</string>
     <string name="pip_pause" msgid="8412075640017218862">"暂停"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"按住"<b>"主屏幕"</b>"即可控制 PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"按住主屏幕\n按钮即可控制 PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"知道了"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 13a6682..c7b2fff 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -73,6 +73,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_to_save_unknown_text" msgid="7887826345701753830">"儲存螢幕擷圖時發生問題。"</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"由於儲存空間有限,因此無法儲存螢幕擷取畫面。"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"此應用程式或您的機構禁止擷取螢幕畫面。"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB 檔案傳輸選項"</string>
@@ -510,9 +511,9 @@
     <string name="headset" msgid="4534219457597457353">"耳機"</string>
     <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"已連接至耳機"</string>
     <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"已連接至耳機"</string>
-    <string name="data_saver" msgid="5037565123367048522">"數據節省程式"</string>
-    <string name="accessibility_data_saver_on" msgid="8454111686783887148">"數據節省程式已開啟"</string>
-    <string name="accessibility_data_saver_off" msgid="8841582529453005337">"數據節省程式已關閉"</string>
+    <string name="data_saver" msgid="5037565123367048522">"數據節省模式"</string>
+    <string name="accessibility_data_saver_on" msgid="8454111686783887148">"數據節省模式已開啟"</string>
+    <string name="accessibility_data_saver_off" msgid="8841582529453005337">"數據節省模式已關閉"</string>
     <string name="switch_bar_on" msgid="1142437840752794229">"開啟"</string>
     <string name="switch_bar_off" msgid="8803270596930432874">"關閉"</string>
     <string name="nav_bar" msgid="1993221402773877607">"導覽列"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings_tv.xml b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml
index 8707d32..8e5a2df 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings_tv.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"關閉 PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"全螢幕"</string>
     <string name="pip_play" msgid="674145557658227044">"播放"</string>
     <string name="pip_pause" msgid="8412075640017218862">"暫停"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"按住"<b>"主按鈕"</b>"即可控制 PIP"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"按住主按鈕\n即可控制 PIP"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"知道了"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index e7172ac..636f2fb 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"已拍攝螢幕擷取畫面。"</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"輕觸即可查看螢幕擷取畫面。"</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"無法拍攝螢幕擷取畫面。"</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"由於儲存空間有限,因此無法儲存螢幕擷取畫面。"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"這個應用程式或貴機構禁止擷取螢幕畫面。"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB 檔案傳輸選項"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
index 8707d32..60edac2 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
@@ -19,15 +19,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for pip_close (3480680679023423574) -->
-    <skip />
+    <string name="pip_close" msgid="3480680679023423574">"關閉子母畫面"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"全螢幕"</string>
     <string name="pip_play" msgid="674145557658227044">"播放"</string>
     <string name="pip_pause" msgid="8412075640017218862">"暫停"</string>
-    <!-- no translation found for pip_hold_home (340086535668778109) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_description (2627737116380318292) -->
-    <skip />
-    <!-- no translation found for pip_onboarding_button (3957426748484904611) -->
-    <skip />
+    <string name="pip_hold_home" msgid="340086535668778109">"按住「主畫面」"<b></b>"按鈕即可控制子母畫面"</string>
+    <string name="pip_onboarding_description" msgid="2627737116380318292">"按住「主畫面」按鈕\n即可控制子母畫面"</string>
+    <string name="pip_onboarding_button" msgid="3957426748484904611">"我知道了"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 5868b2a..8d2a51b 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -73,6 +73,8 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Umfanekiso weskrini uqoshiwe"</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Thinta ukubona imifanekiso yakho yeskrini"</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Yehlulekile ukulondoloza umfanekiso weskrini."</string>
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) -->
+    <skip />
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Ayikwazi ukulondoloza isithombe-skrini ngenxa yesikhala sesitoreji esikhawulelwe."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Ukuthatha izithombe-skrini akuvunyelwe uhlelo lokusebenza noma inhlangano yakho."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Okukhethwa kokudluliswa kwefayela ye-USB"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index e50f975..6a9f456 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -178,7 +178,7 @@
     <dimen name="qs_date_alarm_anim_translation">22dp</dimen>
     <dimen name="qs_date_collapsed_text_size">14sp</dimen>
     <dimen name="qs_date_text_size">16sp</dimen>
-    <dimen name="qs_header_gear_translation">150dp</dimen>
+    <dimen name="qs_header_gear_translation">16dp</dimen>
     <dimen name="qs_page_indicator_size">12dp</dimen>
     <dimen name="qs_tile_icon_size">24dp</dimen>
     <dimen name="qs_tile_text_size">12sp</dimen>
diff --git a/packages/SystemUI/res/values/strings_tv.xml b/packages/SystemUI/res/values/strings_tv.xml
index b35038d..0e1fe8f 100644
--- a/packages/SystemUI/res/values/strings_tv.xml
+++ b/packages/SystemUI/res/values/strings_tv.xml
@@ -27,13 +27,12 @@
     <string name="pip_play">Play</string>
     <!-- Button to pause the current media on picture-in-picture (PIP) [CHAR LIMIT=16] -->
     <string name="pip_pause">Pause</string>
-    <!-- Overlay text on picture-in-picture (PIP) to indicate that longpress HOME key to control PIP [CHAR LIMIT=25] -->
+    <!-- Overlay text on picture-in-picture (PIP) to indicate that longpress HOME key to control PIP [CHAR LIMIT=52] -->
     <string name="pip_hold_home">Hold <b>HOME</b> to control PIP</string>
     <!-- Picture-in-Picture (PIP) onboarding screen -->
     <eat-comment />
-    <!-- Description for picture-in-picture (PIP) onboarding screen to indicate that longpress HOME key to control PIP.
-         Line break is needed as if we have CHAR LIMIT=25. [CHAR LIMIT=NONE] -->
-    <string name="pip_onboarding_description">Press and hold the HOME\nbutton to control PIP</string>
+    <!-- Description for picture-in-picture (PIP) onboarding screen to indicate that longpress HOME key to control PIP. [CHAR LIMIT=NONE] -->
+    <string name="pip_onboarding_description">Press and hold the HOME button to control PIP</string>
     <!-- Button to close picture-in-picture (PIP) onboarding screen. -->
     <string name="pip_onboarding_button">Got it</string>
     <!-- Font for Recents -->
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
index 937f7d3..0d822cb 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
@@ -166,7 +166,9 @@
      */
     public boolean isFalseTouch() {
         if (FalsingLog.ENABLED) {
-            if (!mSessionActive) {
+            // We're getting some false wtfs from touches that happen after the device went
+            // to sleep. Only report missing sessions that happen when the device is interactive.
+            if (!mSessionActive && mContext.getSystemService(PowerManager.class).isInteractive()) {
                 FalsingLog.wtf("isFalseTouch", new StringBuilder()
                         .append("Session is not active, yet there's a query for a false touch.")
                         .append(" enabled=").append(isEnabled() ? 1 : 0)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 312d3c5..02b860c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -811,7 +811,7 @@
         intent.putExtra("seq", mDelayedShowingSequence);
         PendingIntent sender = PendingIntent.getBroadcast(mContext,
                 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, sender);
+        mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, sender);
         if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = "
                          + mDelayedShowingSequence);
         doKeyguardLaterForChildProfilesLocked();
@@ -828,7 +828,8 @@
                 lockIntent.putExtra(Intent.EXTRA_USER_ID, info.id);
                 PendingIntent lockSender = PendingIntent.getBroadcast(
                         mContext, 0, lockIntent, PendingIntent.FLAG_CANCEL_CURRENT);
-                mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, userWhen, lockSender);
+                mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                        userWhen, lockSender);
             }
         }
     }
@@ -1542,13 +1543,22 @@
             try {
                 mStatusBarKeyguardViewManager.keyguardGoingAway();
 
+                int flags = 0;
+                if (mStatusBarKeyguardViewManager.shouldDisableWindowAnimationsForUnlock()
+                        || mWakeAndUnlocking) {
+                    flags |= WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
+                }
+                if (mStatusBarKeyguardViewManager.isGoingToNotificationShade()) {
+                    flags |= WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
+                }
+                if (mStatusBarKeyguardViewManager.isUnlockWithWallpaper()) {
+                    flags |= WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
+                }
+
                 // Don't actually hide the Keyguard at the moment, wait for window
                 // manager until it tells us it's safe to do so with
                 // startKeyguardExitAnimation.
-                ActivityManagerNative.getDefault().keyguardGoingAway(
-                        mStatusBarKeyguardViewManager.shouldDisableWindowAnimationsForUnlock()
-                                || mWakeAndUnlocking,
-                        mStatusBarKeyguardViewManager.isGoingToNotificationShade());
+                ActivityManagerNative.getDefault().keyguardGoingAway(flags);
             } catch (RemoteException e) {
                 Log.e(TAG, "Error while calling WindowManager", e);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index f601f90..815c679 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -41,6 +41,7 @@
     private static final String MOVE_FULL_ROWS = "sysui_qs_move_whole_rows";
 
     public static final float EXPANDED_TILE_DELAY = .7f;
+    private static final float LAST_ROW_EXPANDED_DELAY = .84f;
 
     private final ArrayList<View> mAllViews = new ArrayList<>();
     private final ArrayList<View> mTopFiveQs = new ArrayList<>();
@@ -56,6 +57,7 @@
     private TouchAnimator mTranslationXAnimator;
     private TouchAnimator mTranslationYAnimator;
     private TouchAnimator mNonfirstPageAnimator;
+    private TouchAnimator mLastRowAnimator;
 
     private boolean mOnKeyguard;
 
@@ -87,6 +89,7 @@
 
     public void setHost(QSTileHost qsh) {
         qsh.addCallback(this);
+        updateAnimators();
     }
 
     @Override
@@ -129,20 +132,21 @@
         TouchAnimator.Builder firstPageBuilder = new Builder();
         TouchAnimator.Builder translationXBuilder = new Builder();
         TouchAnimator.Builder translationYBuilder = new Builder();
-        TouchAnimator.Builder firstPageDelayedBuilder = new Builder();
+        TouchAnimator.Builder lastRowBuilder = new Builder();
+
+        if (mQsPanel.getHost() == null) return;
         Collection<QSTile<?>> tiles = mQsPanel.getHost().getTiles();
         int count = 0;
         int[] loc1 = new int[2];
         int[] loc2 = new int[2];
         int lastYDiff = 0;
-        firstPageDelayedBuilder.setStartDelay(EXPANDED_TILE_DELAY);
-        firstPageBuilder.setListener(this);
-        // Fade in the tiles/labels as we reach the final position.
-        firstPageDelayedBuilder.addFloat(mQsPanel.getTileLayout(), "alpha", 0, 1);
+
         clearAnimationState();
         mAllViews.clear();
         mTopFiveQs.clear();
+
         mAllViews.add((View) mQsPanel.getTileLayout());
+
         for (QSTile<?> tile : tiles) {
             QSTileBaseView tileView = mQsPanel.getTileView(tile);
             final TextView label = ((QSTileView) tileView).getLabel();
@@ -171,22 +175,30 @@
 
                 mTopFiveQs.add(tileIcon);
                 mAllViews.add(tileIcon);
-                mAllViews.add(label);
                 mAllViews.add(quickTileView);
             } else if (mFullRows && isIconInAnimatedRow(count)) {
                 firstPageBuilder.addFloat(tileView, "translationY", mQsPanel.getHeight(), 0);
                 translationYBuilder.addFloat(label, "translationY", -lastYDiff, 0);
                 translationYBuilder.addFloat(tileIcon, "translationY", -lastYDiff, 0);
                 mAllViews.add(tileIcon);
-                mAllViews.add(label);
+            } else {
+                lastRowBuilder.addFloat(tileView, "alpha", 0, 1);
             }
             mAllViews.add(tileView);
             mAllViews.add(label);
             count++;
         }
         if (mAllowFancy) {
-            mFirstPageAnimator = firstPageBuilder.build();
-            mFirstPageDelayedAnimator = firstPageDelayedBuilder.build();
+            mFirstPageAnimator = firstPageBuilder
+                    .setListener(this)
+                    .build();
+            // Fade in the tiles/labels as we reach the final position.
+            mFirstPageDelayedAnimator = new TouchAnimator.Builder()
+                    .setStartDelay(EXPANDED_TILE_DELAY)
+                    .addFloat(mQsPanel.getTileLayout(), "alpha", 0, 1).build();
+            mLastRowAnimator = lastRowBuilder
+                    .setStartDelay(LAST_ROW_EXPANDED_DELAY)
+                    .build();
             Path path = new Path();
             path.moveTo(0, 0);
             path.cubicTo(0, 0, 0, 1, 1, 1);
@@ -235,6 +247,7 @@
             mFirstPageDelayedAnimator.setPosition(position);
             mTranslationXAnimator.setPosition(position);
             mTranslationYAnimator.setPosition(position);
+            mLastRowAnimator.setPosition(position);
         } else {
             mNonfirstPageAnimator.setPosition(position);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index d0e034b..ab90179 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -26,6 +26,8 @@
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile.SignalState;
 import com.android.systemui.qs.QSTile.State;
+import com.android.systemui.qs.customize.QSCustomizer;
+import com.android.systemui.statusbar.phone.QSTileHost;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
 
@@ -95,9 +97,17 @@
         return new QSTileBaseView(mContext, tile.createTileView(mContext));
     }
 
+    @Override
+    public void setHost(QSTileHost host, QSCustomizer customizer) {
+        super.setHost(host, customizer);
+        setTiles(mHost.getTiles());
+    }
+
     public void setMaxTiles(int maxTiles) {
         mMaxTiles = maxTiles;
-        setTiles(mHost.getTiles());
+        if (mHost != null) {
+            setTiles(mHost.getTiles());
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 93cb952..246f15e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -745,6 +745,9 @@
 
     public Animator getTranslateViewAnimator(final float leftTarget,
             AnimatorUpdateListener listener) {
+        if (mTranslateAnim != null) {
+            mTranslateAnim.cancel();
+        }
         if (areGutsExposed()) {
             // No translation if guts are exposed.
             return null;
@@ -769,19 +772,27 @@
                     if (listener != null) {
                         translateAnim.addUpdateListener(listener);
                     }
-                }
-                translateAnim.addListener(new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator anim) {
-                        if (mSettingsIconRow != null && leftTarget == 0) {
-                            mSettingsIconRow.resetState();
+                    translateAnim.addListener(new AnimatorListenerAdapter() {
+                        boolean cancelled = false;
+
+                        @Override
+                        public void onAnimationCancel(Animator anim) {
+                            cancelled = true;
                         }
-                        mTranslateAnim = null;
-                    }
-                });
+
+                        @Override
+                        public void onAnimationEnd(Animator anim) {
+                            if (!cancelled && mSettingsIconRow != null && leftTarget == 0) {
+                                mSettingsIconRow.resetState();
+                                mTranslateAnim = null;
+                            }
+                        }
+                    });
+                }
                 set.play(translateAnim);
             }
         }
+        mTranslateAnim = set;
         return set;
     }
 
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 906bd0f..bf58611 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1887,10 +1887,16 @@
             if (mBackdrop.getVisibility() != View.VISIBLE) {
                 mBackdrop.setVisibility(View.VISIBLE);
                 if (allowEnterAnimation) {
-                    mBackdrop.animate().alpha(1f);
+                    mBackdrop.animate().alpha(1f).withEndAction(new Runnable() {
+                        @Override
+                        public void run() {
+                            mStatusBarWindowManager.setBackdropShowing(true);
+                        }
+                    });
                 } else {
                     mBackdrop.animate().cancel();
                     mBackdrop.setAlpha(1f);
+                    mStatusBarWindowManager.setBackdropShowing(true);
                 }
                 metaDataChanged = true;
                 if (DEBUG_MEDIA) {
@@ -1948,7 +1954,9 @@
                     // We are unlocking directly - no animation!
                     mBackdrop.setVisibility(View.GONE);
                     mBackdropBack.setImageDrawable(null);
+                    mStatusBarWindowManager.setBackdropShowing(false);
                 } else {
+                    mStatusBarWindowManager.setBackdropShowing(false);
                     mBackdrop.animate()
                             // Never let the alpha become zero - otherwise the RenderNode
                             // won't draw anything and uninitialized memory will show through
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
index b29c807..8f329c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -83,7 +83,6 @@
     private float mDateScaleFactor;
     private float mGearTranslation;
 
-    private TouchAnimator mAnimator;
     private TouchAnimator mSecondHalfAnimator;
     private TouchAnimator mFirstHalfAnimator;
     private TouchAnimator mDateSizeAnimator;
@@ -154,12 +153,7 @@
         mDateScaleFactor = dateExpandedSize / dateCollapsedSize;
         updateDateTimePosition();
 
-        mAnimator = new TouchAnimator.Builder()
-                .addFloat(mSettingsContainer, "translationY", -mGearTranslation, 0)
-                .addFloat(mMultiUserSwitch, "translationY", -mGearTranslation, 0)
-                .build();
         mSecondHalfAnimator = new TouchAnimator.Builder()
-                .addFloat(mSettingsButton, "rotation", -180, 0)
                 .addFloat(mAlarmStatus, "alpha", 0, 1)
                 .addFloat(mEmergencyOnly, "alpha", 0, 1)
                 .setStartDelay(.5f)
@@ -174,6 +168,9 @@
                 .setStartDelay(.36f)
                 .build();
         mSettingsAlpha = new TouchAnimator.Builder()
+                .addFloat(mSettingsContainer, "translationY", -mGearTranslation, 0)
+                .addFloat(mMultiUserSwitch, "translationY", -mGearTranslation, 0)
+                .addFloat(mSettingsButton, "rotation", -90, 0)
                 .addFloat(mSettingsContainer, "alpha", 0, 1)
                 .addFloat(mMultiUserSwitch, "alpha", 0, 1)
                 .setStartDelay(QSAnimator.EXPANDED_TILE_DELAY)
@@ -211,7 +208,6 @@
     @Override
     public void setExpansion(float headerExpansionFraction) {
         mExpansionAmount = headerExpansionFraction;
-        mAnimator.setPosition(headerExpansionFraction);
         mSecondHalfAnimator.setPosition(headerExpansionFraction);
         mFirstHalfAnimator.setPosition(headerExpansionFraction);
         mDateSizeAnimator.setPosition(headerExpansionFraction);
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 2ba1562..117e2b3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -227,6 +227,10 @@
         mStatusBarWindowManager.setKeyguardNeedsInput(needsInput);
     }
 
+    public boolean isUnlockWithWallpaper() {
+        return mStatusBarWindowManager.isShowingWallpaper();
+    }
+
     public void setOccluded(boolean occluded) {
         if (occluded && !mOccluded && mShowing) {
             if (mPhoneStatusBar.isInLaunchTransition()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index 77ece93..ada7450 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -100,12 +100,16 @@
 
     private void applyKeyguardFlags(State state) {
         if (state.keyguardShowing) {
-            mLpChanged.flags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
             mLpChanged.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
         } else {
-            mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
             mLpChanged.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
         }
+
+        if (state.keyguardShowing && !state.backdropShowing) {
+            mLpChanged.flags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+        } else {
+            mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+        }
     }
 
     private void adjustScreenOrientation(State state) {
@@ -255,6 +259,11 @@
         apply(mCurrentState);
     }
 
+    public void setBackdropShowing(boolean showing) {
+        mCurrentState.backdropShowing = showing;
+        apply(mCurrentState);
+    }
+
     public void setKeyguardFadingAway(boolean keyguardFadingAway) {
         mCurrentState.keyguardFadingAway = keyguardFadingAway;
         apply(mCurrentState);
@@ -323,6 +332,10 @@
         pw.println(mCurrentState);
     }
 
+    public boolean isShowingWallpaper() {
+        return !mCurrentState.backdropShowing;
+    }
+
     private static class State {
         boolean keyguardShowing;
         boolean keyguardOccluded;
@@ -338,6 +351,7 @@
         boolean forceCollapsed;
         boolean forceDozeBrightness;
         boolean forceUserActivity;
+        boolean backdropShowing;
 
         /**
          * The {@link BaseStatusBar} state from the status bar.
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index d36a1d7..d929519 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -1996,6 +1996,22 @@
     // Logs that the user docks window via shortcut key.
     WINDOW_DOCK_SHORTCUTS = 352;
 
+    // User already denied access to the request folder; action takes an integer
+    // representing the folder's index on Environment.STANDARD_DIRECTORIES
+    ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED_BY_FOLDER = 353;
+
+    // User already denied access to the request folder; action pass package name
+    // of calling package.
+    ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED_BY_PACKAGE = 354;
+
+    // User denied access to the request folder and checked 'Do not ask again';
+    // action takes an integer representing the folder's index on Environment.STANDARD_DIRECTORIES
+    ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST_BY_FOLDER = 355;
+
+    // User denied access to the request folder and checked 'Do not ask again';
+    // action pass package name of calling package.
+    ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST_BY_PACKAGE = 356;
+
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
   }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java
index 3ac81f6..562d950 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java
@@ -63,14 +63,6 @@
         void onDoubleTapAndHold(MotionEvent event, int policyFlags);
 
         /**
-         * Called when the user touches the screen on the second tap of a double
-         * tap.
-         *
-         * @return true if the event is consumed, else false
-         */
-        boolean onDoubleTapStarted();
-
-        /**
          * Called when the user lifts their finger on the second tap of a double
          * tap.
          *
@@ -246,13 +238,20 @@
                         mBaseY = y;
                         mBaseTime = time;
 
+                        // Since the pointer has moved, this is not a double
+                        // tap.
+                        mFirstTapDetected = false;
+                        mDoubleTapDetected = false;
+
                         // If this hasn't been confirmed as a gesture yet, send
                         // the event.
                         if (!mGestureStarted) {
                             mGestureStarted = true;
                             return mListener.onGestureStarted();
                         }
-                    } else {
+                    } else if (!mFirstTapDetected) {
+                        // The finger may not move if they are double tapping.
+                        // In that case, we shouldn't cancel the gesture.
                         final long timeDelta = time - mBaseTime;
                         final long threshold = mGestureStarted ?
                             CANCEL_ON_PAUSE_THRESHOLD_STARTED_MS :
@@ -371,7 +370,7 @@
         // The processing of the double tap is deferred until the finger is
         // lifted, so that we can detect a long press on the second tap.
         mDoubleTapDetected = true;
-        return mListener.onDoubleTapStarted();
+        return false;
     }
 
     private void maybeSendLongPress(MotionEvent event, int policyFlags) {
diff --git a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
index cd8b792..3cc991c 100644
--- a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
@@ -390,11 +390,6 @@
     }
 
     @Override
-    public boolean onDoubleTapStarted() {
-        return true;
-    }
-
-    @Override
     public boolean onDoubleTap(MotionEvent event, int policyFlags) {
         // Ignore the event if we aren't touch exploring.
         if (mCurrentState != STATE_TOUCH_EXPLORING) {
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 3659a40..a4f85db 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -210,6 +210,7 @@
     private final UserManager mUserManager;
     private final AppOpsManager mAppOpsManager;
     private final KeyguardManager mKeyguardManager;
+    private final DevicePolicyManagerInternal mDevicePolicyManagerInternal;
 
     private final SecurityPolicy mSecurityPolicy;
 
@@ -232,6 +233,7 @@
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
         mKeyguardManager = (KeyguardManager) mContext.getSystemService(KEYGUARD_SERVICE);
+        mDevicePolicyManagerInternal = LocalServices.getService(DevicePolicyManagerInternal.class);
         mSaveStateHandler = BackgroundThread.getHandler();
         mCallbackHandler = new CallbackHandler(mContext.getMainLooper());
         mBackupRestoreController = new BackupRestoreController();
@@ -298,11 +300,9 @@
     }
 
     private void registerOnCrossProfileProvidersChangedListener() {
-        DevicePolicyManagerInternal devicePolicyManager = LocalServices.getService(
-                DevicePolicyManagerInternal.class);
         // The device policy is an optional component.
-        if (devicePolicyManager != null) {
-            devicePolicyManager.addOnCrossProfileWidgetProvidersChangeListener(this);
+        if (mDevicePolicyManagerInternal != null) {
+            mDevicePolicyManagerInternal.addOnCrossProfileWidgetProvidersChangeListener(this);
         }
     }
 
@@ -588,7 +588,7 @@
             try {
                 UserInfo userInfo = mUserManager.getUserInfo(providerUserId);
                 showBadge = userInfo.isManagedProfile();
-                onClickIntent = UnlaunchableAppActivity.createPackageSuspendedDialogIntent(
+                onClickIntent = mDevicePolicyManagerInternal.createPackageSuspendedDialogIntent(
                         providerPackage, providerUserId);
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -3574,15 +3574,12 @@
         }
 
         public boolean isProviderWhiteListed(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) {
+            if (mDevicePolicyManagerInternal == null) {
                 return false;
             }
 
-            List<String> crossProfilePackages = devicePolicyManager
+            List<String> crossProfilePackages = mDevicePolicyManagerInternal
                     .getCrossProfileWidgetProviders(profileId);
 
             return crossProfilePackages.contains(packageName);
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index e241a4a..799a763 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -761,6 +761,11 @@
         if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {
             if (DBG) Slog.d(TAG, "Auto-enabling Bluetooth.");
             sendEnableMsg(mQuietEnableExternal);
+        } else if (!isNameAndAddressSet()) {
+            if (DBG) Slog.d(TAG, "Getting adapter name and address");
+            enable();
+            waitForOnOff(true, false);
+            disable(true);
         }
     }
 
@@ -1001,6 +1006,7 @@
                 }
             }
         }
+
         // mAddress is accessed from outside.
         // It is alright without a lock. Here, bluetooth is off, no other thread is
         // changing mAddress
@@ -1181,6 +1187,15 @@
                             Slog.e(TAG,"Unable to call configHciSnoopLog", e);
                         }
 
+                        if (!isNameAndAddressSet()) {
+                            try {
+                                storeNameAndAddress(mBluetooth.getName(),
+                                                    mBluetooth.getAddress());
+                            } catch (RemoteException re) {
+                                Slog.e(TAG, "Unable to grab names", re);
+                            }
+                        }
+
                         //Register callback object
                         try {
                             mBluetooth.registerCallback(mBluetoothCallback);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 86040c2..3c13577 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -3253,8 +3253,12 @@
             }
             int user = UserHandle.getUserId(Binder.getCallingUid());
             synchronized(mVpns) {
-                setLockdownTracker(new LockdownVpnTracker(mContext, mNetd, this, mVpns.get(user),
-                            profile));
+                Vpn vpn = mVpns.get(user);
+                if (vpn == null) {
+                    Slog.w(TAG, "VPN for user " + user + " not ready yet. Skipping lockdown");
+                    return false;
+                }
+                setLockdownTracker(new LockdownVpnTracker(mContext, mNetd, this, vpn, profile));
             }
         } else {
             setLockdownTracker(null);
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 11888ff..4198af9 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -67,7 +67,8 @@
         "/system/bin/audioserver",
         "/system/bin/mediaserver",
         "/system/bin/sdcard",
-        "/system/bin/surfaceflinger"
+        "/system/bin/surfaceflinger",
+        "media.log"
     };
 
     static Watchdog sWatchdog;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 07f668b..95dbd0f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5347,6 +5347,7 @@
                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
                         Uri.fromParts("package", packageName, null));
                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
+                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
                         null, null, 0, null, null, null, null, false, false, userId);
             } catch (RemoteException e) {
@@ -6496,15 +6497,13 @@
     }
 
     @Override
-    public void keyguardGoingAway(boolean disableWindowAnimations,
-            boolean keyguardGoingToNotificationShade) {
+    public void keyguardGoingAway(int flags) {
         enforceNotIsolatedCaller("keyguardGoingAway");
         final long token = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
                 if (DEBUG_LOCKSCREEN) logLockScreen("");
-                mWindowManager.keyguardGoingAway(disableWindowAnimations,
-                        keyguardGoingToNotificationShade);
+                mWindowManager.keyguardGoingAway(flags);
                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
                     updateSleepIfNeededLocked();
@@ -11197,7 +11196,6 @@
     }
 
     void finishRunningVoiceLocked() {
-        Slog.d(TAG, "finishRunningVoiceLocked()  >>>>");
         if (mRunningVoice != null) {
             mRunningVoice = null;
             mVoiceWakeLock.release();
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 09542cb..26eaa8a 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -2213,10 +2213,11 @@
 
         ActivityStack lastStack = mStackSupervisor.getLastStack();
         if (next.app != null && next.app.thread != null) {
-            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next);
+            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next
+                    + " stopped=" + next.stopped + " visible=" + next.visible);
 
             // This activity is now becoming visible.
-            if (!next.visible) {
+            if (!next.visible || next.stopped) {
                 mWindowManager.setAppVisibility(next.appToken, true);
             }
 
diff --git a/services/core/java/com/android/server/am/ActivityStartInterceptor.java b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
index e4b4c2d..13d90e3 100644
--- a/services/core/java/com/android/server/am/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
@@ -29,6 +29,7 @@
 import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;
 
 import android.app.KeyguardManager;
+import android.app.admin.DevicePolicyManagerInternal;
 import android.content.IIntentSender;
 import android.content.Intent;
 import android.content.IntentSender;
@@ -40,6 +41,7 @@
 import android.os.UserManager;
 
 import com.android.internal.app.UnlaunchableAppActivity;
+import com.android.server.LocalServices;
 
 /**
  * A class that contains activity intercepting logic for {@link ActivityStarter#startActivityLocked}
@@ -133,8 +135,10 @@
                 (mAInfo.applicationInfo.flags & FLAG_SUSPENDED) == 0) {
             return false;
         }
-        mIntent = UnlaunchableAppActivity.createPackageSuspendedDialogIntent(mAInfo.packageName,
-                mUserId);
+        DevicePolicyManagerInternal devicePolicyManager = LocalServices.getService(
+                DevicePolicyManagerInternal.class);
+        mIntent = devicePolicyManager.createPackageSuspendedDialogIntent(
+                mAInfo.packageName, mUserId);
         mCallingPid = mRealCallingPid;
         mCallingUid = mRealCallingUid;
         mResolvedType = null;
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 83ad2a7..fa62c98 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1327,19 +1327,31 @@
                     intentActivity.setTaskToAffiliateWith(mSourceRecord.task);
                 }
                 mMovedHome = true;
-                final ActivityStack launchStack =
-                        getLaunchStack(mStartActivity, mLaunchFlags, mStartActivity.task,
-                                mOptions, true);
-                if (launchStack == null || launchStack == mTargetStack) {
-                    // We only want to move to the front, if we aren't going to launch on a
-                    // different stack. If we launch on a different stack, we will put the
-                    // task on top there.
-                    mTargetStack.moveTaskToFrontLocked(intentActivity.task, mNoAnimation,
-                            mOptions, mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
-                    mMovedToFront = true;
+
+                // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities
+                // will be cleared soon by ActivityStarter in setTaskFromIntentActivity().
+                // So no point resuming any of the activities here, it just wastes one extra
+                // resuming, plus enter AND exit transitions.
+                // Here we only want to bring the target stack forward. Transition will be applied
+                // to the new activity that's started after the old ones are gone.
+                final boolean willClearTask =
+                        (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
+                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
+                if (!willClearTask) {
+                    final ActivityStack launchStack = getLaunchStack(
+                            mStartActivity, mLaunchFlags, mStartActivity.task, mOptions, true);
+                    if (launchStack == null || launchStack == mTargetStack) {
+                        // We only want to move to the front, if we aren't going to launch on a
+                        // different stack. If we launch on a different stack, we will put the
+                        // task on top there.
+                        mTargetStack.moveTaskToFrontLocked(
+                                intentActivity.task, mNoAnimation, mOptions,
+                                mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
+                        mMovedToFront = true;
+                    }
+                    mOptions = null;
                 }
                 updateTaskReturnToType(intentActivity.task, mLaunchFlags, focusStack);
-                mOptions = null;
             }
         }
         if (!mMovedToFront && mDoResume) {
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index 73da427..bce7733 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -688,12 +688,11 @@
             // Time how long it takes to get a response to our request
             long requestTimestamp = SystemClock.elapsedRealtime();
 
-            urlConnection.getInputStream();
+            httpResponseCode = urlConnection.getResponseCode();
 
             // Time how long it takes to get a response to our request
             long responseTimestamp = SystemClock.elapsedRealtime();
 
-            httpResponseCode = urlConnection.getResponseCode();
             validationLog("isCaptivePortal: ret=" + httpResponseCode +
                     " headers=" + urlConnection.getHeaderFields());
             // NOTE: We may want to consider an "HTTP/1.0 204" response to be a captive
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 212e077..03191a0 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -18,12 +18,16 @@
 
 import android.Manifest;
 import android.accounts.Account;
+import android.annotation.Nullable;
 import android.app.ActivityManager;
+import android.app.AppOpsManager;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.IContentService;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.ISyncStatusObserver;
 import android.content.PeriodicSync;
 import android.content.SyncAdapterType;
@@ -32,6 +36,7 @@
 import android.content.SyncStatusInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
+import android.content.pm.ProviderInfo;
 import android.database.IContentObserver;
 import android.database.sqlite.SQLiteException;
 import android.net.Uri;
@@ -44,30 +49,64 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.SparseIntArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.internal.util.Preconditions;
 import com.android.server.LocalServices;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.security.InvalidParameterException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * {@hide}
  */
 public final class ContentService extends IContentService.Stub {
     private static final String TAG = "ContentService";
+
     private Context mContext;
     private boolean mFactoryTest;
+
     private final ObserverNode mRootNode = new ObserverNode("");
+
     private SyncManager mSyncManager = null;
     private final Object mSyncManagerLock = new Object();
 
+    /**
+     * Map from userId to providerPackageName to [clientPackageName, uri] to
+     * value. This structure is carefully optimized to keep invalidation logic
+     * as cheap as possible.
+     */
+    @GuardedBy("mCache")
+    private final SparseArray<ArrayMap<String, ArrayMap<Pair<String, Uri>, Bundle>>>
+            mCache = new SparseArray<>();
+
+    private BroadcastReceiver mCacheReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final Uri data = intent.getData();
+            if (data != null) {
+                final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+                        UserHandle.USER_NULL);
+                final String packageName = data.getSchemeSpecificPart();
+                invalidateCacheLocked(userId, packageName, null);
+            }
+        }
+    };
+
     private SyncManager getSyncManager() {
         if (SystemProperties.getBoolean("config.disable_network", false)) {
             return null;
@@ -85,13 +124,15 @@
     }
 
     @Override
-    protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+    protected synchronized void dump(FileDescriptor fd, PrintWriter pw_, String[] args) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.DUMP,
                 "caller doesn't have the DUMP permission");
 
+        final IndentingPrintWriter pw = new IndentingPrintWriter(pw_, "  ");
+
         // This makes it so that future permission checks will be in the context of this
         // process rather than the caller's process. We will restore this before returning.
-        long identityToken = clearCallingIdentity();
+        final long identityToken = clearCallingIdentity();
         try {
             if (mSyncManager == null) {
                 pw.println("No SyncManager created!  (Disk full?)");
@@ -132,6 +173,19 @@
                 pw.print(" Total number of nodes: "); pw.println(counts[0]);
                 pw.print(" Total number of observers: "); pw.println(counts[1]);
             }
+
+            synchronized (mCache) {
+                pw.println();
+                pw.println("Cached content:");
+                pw.increaseIndent();
+                for (int i = 0; i < mCache.size(); i++) {
+                    pw.println("User " + mCache.keyAt(i) + ":");
+                    pw.increaseIndent();
+                    pw.println(mCache.valueAt(i));
+                    pw.decreaseIndent();
+                }
+                pw.decreaseIndent();
+            }
         } finally {
             restoreCallingIdentity(identityToken);
         }
@@ -167,6 +221,15 @@
                         return getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
                     }
                 });
+
+        final IntentFilter packageFilter = new IntentFilter();
+        packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        packageFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
+        packageFilter.addDataScheme("package");
+        mContext.registerReceiverAsUser(mCacheReceiver, UserHandle.ALL,
+                packageFilter, null, null);
     }
 
     public void systemReady() {
@@ -312,6 +375,11 @@
                             uri.getAuthority());
                 }
             }
+
+            synchronized (mCache) {
+                final String providerPackageName = getProviderPackageName(uri);
+                invalidateCacheLocked(userHandle, providerPackageName, uri);
+            }
         } finally {
             restoreCallingIdentity(identityToken);
         }
@@ -915,6 +983,86 @@
         }
     }
 
+    private @Nullable String getProviderPackageName(Uri uri) {
+        final ProviderInfo pi = mContext.getPackageManager()
+                .resolveContentProvider(uri.getAuthority(), 0);
+        return (pi != null) ? pi.packageName : null;
+    }
+
+    private ArrayMap<Pair<String, Uri>, Bundle> findOrCreateCacheLocked(int userId,
+            String providerPackageName) {
+        ArrayMap<String, ArrayMap<Pair<String, Uri>, Bundle>> userCache = mCache.get(userId);
+        if (userCache == null) {
+            userCache = new ArrayMap<>();
+            mCache.put(userId, userCache);
+        }
+        ArrayMap<Pair<String, Uri>, Bundle> packageCache = userCache.get(providerPackageName);
+        if (packageCache == null) {
+            packageCache = new ArrayMap<>();
+            userCache.put(providerPackageName, packageCache);
+        }
+        return packageCache;
+    }
+
+    private void invalidateCacheLocked(int userId, String providerPackageName, Uri uri) {
+        ArrayMap<String, ArrayMap<Pair<String, Uri>, Bundle>> userCache = mCache.get(userId);
+        if (userCache == null) return;
+
+        ArrayMap<Pair<String, Uri>, Bundle> packageCache = userCache.get(providerPackageName);
+        if (packageCache == null) return;
+
+        if (uri != null) {
+            for (int i = 0; i < packageCache.size();) {
+                final Uri key = packageCache.keyAt(i).second;
+                if (Objects.equals(key, uri)) {
+                    packageCache.removeAt(i);
+                } else {
+                    i++;
+                }
+            }
+        } else {
+            packageCache.clear();
+        }
+    }
+
+    @Override
+    public void putCache(String packageName, Uri key, Bundle value, int userId) {
+        enforceCrossUserPermission(userId, TAG);
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CACHE_CONTENT, TAG);
+        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
+                packageName);
+
+        final String providerPackageName = getProviderPackageName(key);
+        final Pair<String, Uri> fullKey = Pair.create(packageName, key);
+
+        synchronized (mCache) {
+            final ArrayMap<Pair<String, Uri>, Bundle> cache = findOrCreateCacheLocked(userId,
+                    providerPackageName);
+            if (value != null) {
+                cache.put(fullKey, value);
+            } else {
+                cache.remove(fullKey);
+            }
+        }
+    }
+
+    @Override
+    public Bundle getCache(String packageName, Uri key, int userId) {
+        enforceCrossUserPermission(userId, TAG);
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CACHE_CONTENT, TAG);
+        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
+                packageName);
+
+        final String providerPackageName = getProviderPackageName(key);
+        final Pair<String, Uri> fullKey = Pair.create(packageName, key);
+
+        synchronized (mCache) {
+            final ArrayMap<Pair<String, Uri>, Bundle> cache = findOrCreateCacheLocked(userId,
+                    providerPackageName);
+            return cache.get(fullKey);
+        }
+    }
+
     public static ContentService main(Context context, boolean factoryTest) {
         ContentService service = new ContentService(context, factoryTest);
         ServiceManager.addService(ContentResolver.CONTENT_SERVICE_NAME, service);
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index e1d208e..e5342ce 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -78,8 +78,9 @@
 import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
-import android.util.SparseArray;
 
+import com.android.server.LocalServices;
+import com.android.server.job.JobSchedulerInternal;
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 
@@ -113,9 +114,7 @@
  * All scheduled syncs will be passed on to JobScheduler as jobs
  * (See {@link #scheduleSyncOperationH(SyncOperation, long)}. This function schedules a job
  * with JobScheduler with appropriate delay and constraints (according to backoffs and extras).
- * A local copy of each scheduled SyncOperation object is stored in {@link mScheduledSyncs}.This
- * acts as a cache, so that we don't have to query JobScheduler every time we want to get a list of
- * all scheduled operations. The scheduleSyncOperationH function also assigns a unique jobId to each
+ * The scheduleSyncOperationH function also assigns a unique jobId to each
  * SyncOperation.
  *
  * Periodic Syncs:
@@ -129,14 +128,6 @@
  * run at a later time. Similarly, when a sync succeeds, backoff is cleared and all associated syncs
  * are rescheduled. A rescheduled sync will get a new jobId.
  *
- * State of {@link mScheduledSyncs}:
- * Every one-off SyncOperation will be put into this SparseArray when it is scheduled with
- * JobScheduler. And it will be removed once JobScheduler has started the job. Periodic syncs work
- * differently. They will always be present in mScheduledSyncs until the periodic sync is removed.
- * This is to ensure that if a request to add a periodic sync comes in, we add a new one only if a
- * duplicate doesn't exist. At every point of time, mScheduledSyncs and JobScheduler will show the
- * same pending syncs.
- *
  * @hide
  */
 public class SyncManager {
@@ -220,6 +211,7 @@
     private final NotificationManager mNotificationMgr;
     private final IBatteryStats mBatteryStats;
     private JobScheduler mJobScheduler;
+    private JobSchedulerInternal mJobSchedulerInternal;
     private SyncJobService mSyncJobService;
 
     private SyncStorageEngine mSyncStorageEngine;
@@ -235,14 +227,13 @@
 
     protected SyncAdaptersCache mSyncAdapters;
 
-    // Cache of all operations scheduled on the JobScheduler so that JobScheduler doesn't have
-    // to be queried often.
-    private SparseArray<SyncOperation> mScheduledSyncs = new SparseArray<SyncOperation>(32);
     private final Random mRand;
 
-    private boolean isJobIdInUseLockedH(int jobId) {
-        if (mScheduledSyncs.indexOfKey(jobId) >= 0) {
-            return true;
+    private boolean isJobIdInUseLockedH(int jobId, List<JobInfo> pendingJobs) {
+        for (JobInfo job: pendingJobs) {
+            if (job.getId() == jobId) {
+                return true;
+            }
         }
         for (ActiveSyncContext asc: mActiveSyncContexts) {
             if (asc.mSyncOperation.jobId == jobId) {
@@ -253,35 +244,25 @@
     }
 
     private int getUnusedJobIdH() {
-        synchronized (mScheduledSyncs) {
-            int newJobId;
-            do {
-                newJobId = MIN_SYNC_JOB_ID + mRand.nextInt(MAX_SYNC_JOB_ID - MIN_SYNC_JOB_ID);
-            } while (isJobIdInUseLockedH(newJobId));
-            return newJobId;
-        }
+        int newJobId;
+        do {
+            newJobId = MIN_SYNC_JOB_ID + mRand.nextInt(MAX_SYNC_JOB_ID - MIN_SYNC_JOB_ID);
+        } while (isJobIdInUseLockedH(newJobId,
+                mJobSchedulerInternal.getSystemScheduledPendingJobs()));
+        return newJobId;
     }
 
-    private void addSyncOperationToCache(SyncOperation op) {
-        synchronized (mScheduledSyncs) {
-            mScheduledSyncs.put(op.jobId, op);
-        }
-    }
-
-    private void removeSyncOperationFromCache(int jobId) {
-        synchronized (mScheduledSyncs) {
-            mScheduledSyncs.remove(jobId);
-        }
-    }
-
-    private List<SyncOperation> getAllPendingSyncsFromCache() {
-        synchronized (mScheduledSyncs) {
-            List<SyncOperation> pending = new ArrayList<SyncOperation>(mScheduledSyncs.size());
-            for (int i=0; i<mScheduledSyncs.size(); i++) {
-                pending.add(mScheduledSyncs.valueAt(i));
+    private List<SyncOperation> getAllPendingSyncs() {
+        verifyJobScheduler();
+        List<JobInfo> pendingJobs = mJobSchedulerInternal.getSystemScheduledPendingJobs();
+        List<SyncOperation> pendingSyncs = new ArrayList<SyncOperation>(pendingJobs.size());
+        for (JobInfo job: pendingJobs) {
+            SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras());
+            if (op != null) {
+                pendingSyncs.add(op);
             }
-            return pending;
         }
+        return pendingSyncs;
     }
 
     private final BroadcastReceiver mStorageIntentReceiver =
@@ -443,7 +424,7 @@
         mSyncHandler.postAtFrontOfQueue(new Runnable() {
             @Override
             public void run() {
-                List<SyncOperation> ops = getAllPendingSyncsFromCache();
+                List<SyncOperation> ops = getAllPendingSyncs();
                 Set<String> cleanedKeys = new HashSet<String>();
                 for (SyncOperation opx: ops) {
                     if (cleanedKeys.contains(opx.key)) {
@@ -455,7 +436,6 @@
                             continue;
                         }
                         if (opx.key.equals(opy.key)) {
-                            removeSyncOperationFromCache(opy.jobId);
                             mJobScheduler.cancel(opy.jobId);
                         }
                     }
@@ -473,18 +453,16 @@
         }
         mJobScheduler = (JobScheduler) mContext.getSystemService(
                 Context.JOB_SCHEDULER_SERVICE);
+        mJobSchedulerInternal = LocalServices.getService(JobSchedulerInternal.class);
         // Get all persisted syncs from JobScheduler
         List<JobInfo> pendingJobs = mJobScheduler.getAllPendingJobs();
-        synchronized (mScheduledSyncs) {
-            for (JobInfo job : pendingJobs) {
-                SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras());
-                if (op != null) {
-                    mScheduledSyncs.put(op.jobId, op);
-                    if (!op.isPeriodic) {
-                        // Set the pending status of this EndPoint to true. Pending icon is
-                        // shown on the settings activity.
-                        mSyncStorageEngine.markPending(op.target, true);
-                    }
+        for (JobInfo job : pendingJobs) {
+            SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras());
+            if (op != null) {
+                if (!op.isPeriodic) {
+                    // Set the pending status of this EndPoint to true. Pending icon is
+                    // shown on the settings activity.
+                    mSyncStorageEngine.markPending(op.target, true);
                 }
             }
         }
@@ -707,7 +685,7 @@
     }
 
     private void setAuthorityPendingState(EndPoint info) {
-        List<SyncOperation> ops = getAllPendingSyncsFromCache();
+        List<SyncOperation> ops = getAllPendingSyncs();
         for (SyncOperation op: ops) {
             if (!op.isPeriodic && op.target.matchesSpec(info)) {
                 getSyncStorageEngine().markPending(info, true);
@@ -927,11 +905,10 @@
 
     private void removeSyncsForAuthority(EndPoint info) {
         verifyJobScheduler();
-        List<SyncOperation> ops = getAllPendingSyncsFromCache();
+        List<SyncOperation> ops = getAllPendingSyncs();
         for (SyncOperation op: ops) {
             if (op.target.matchesSpec(info)) {
-                removeSyncOperationFromCache(op.jobId);
-                getJobScheduler().cancel(op.jobId);
+                 getJobScheduler().cancel(op.jobId);
             }
         }
     }
@@ -961,7 +938,7 @@
      * Get a list of periodic syncs corresponding to the given target.
      */
     public List<PeriodicSync> getPeriodicSyncs(EndPoint target) {
-        List<SyncOperation> ops = getAllPendingSyncsFromCache();
+        List<SyncOperation> ops = getAllPendingSyncs();
         List<PeriodicSync> periodicSyncs = new ArrayList<PeriodicSync>();
 
         for (SyncOperation op: ops) {
@@ -1145,12 +1122,11 @@
      * to current backoff and delayUntil values of this EndPoint.
      */
     private void rescheduleSyncs(EndPoint target) {
-        List<SyncOperation> ops = getAllPendingSyncsFromCache();
+        List<SyncOperation> ops = getAllPendingSyncs();
         int count = 0;
         for (SyncOperation op: ops) {
             if (!op.isPeriodic && op.target.matchesSpec(target)) {
                 count++;
-                removeSyncOperationFromCache(op.jobId);
                 getJobScheduler().cancel(op.jobId);
                 postScheduleSyncMessage(op);
             }
@@ -1251,7 +1227,7 @@
             int duplicatesCount = 0;
             long now = SystemClock.elapsedRealtime();
             syncOperation.expectedRuntime = now + minDelay;
-            List<SyncOperation> pending = getAllPendingSyncsFromCache();
+            List<SyncOperation> pending = getAllPendingSyncs();
             SyncOperation opWithLeastExpectedRuntime = syncOperation;
             for (SyncOperation op : pending) {
                 if (op.isPeriodic) {
@@ -1276,7 +1252,6 @@
                         if (isLoggable) {
                             Slog.v(TAG, "Cancelling duplicate sync " + op);
                         }
-                        removeSyncOperationFromCache(op.jobId);
                         getJobScheduler().cancel(op.jobId);
                     }
                 }
@@ -1294,7 +1269,6 @@
         if (syncOperation.jobId == SyncOperation.NO_JOB_ID) {
             syncOperation.jobId = getUnusedJobIdH();
         }
-        addSyncOperationToCache(syncOperation);
 
         if (isLoggable) {
             Slog.v(TAG, "scheduling sync operation " + syncOperation.toString());
@@ -1335,10 +1309,9 @@
      * have null account/provider info to specify all accounts/providers.
      */
     public void clearScheduledSyncOperations(SyncStorageEngine.EndPoint info) {
-        List<SyncOperation> ops = getAllPendingSyncsFromCache();
+        List<SyncOperation> ops = getAllPendingSyncs();
         for (SyncOperation op: ops) {
             if (!op.isPeriodic && op.target.matchesSpec(info)) {
-                removeSyncOperationFromCache(op.jobId);
                 getJobScheduler().cancel(op.jobId);
                 getSyncStorageEngine().markPending(op.target, false);
             }
@@ -1353,11 +1326,10 @@
      * @param extras extras bundle to uniquely identify sync.
      */
     public void cancelScheduledSyncOperation(SyncStorageEngine.EndPoint info, Bundle extras) {
-        List<SyncOperation> ops = getAllPendingSyncsFromCache();
+        List<SyncOperation> ops = getAllPendingSyncs();
         for (SyncOperation op: ops) {
             if (!op.isPeriodic && op.target.matchesSpec(info)
                     && syncExtrasEquals(extras, op.extras, false)) {
-                removeSyncOperationFromCache(op.jobId);
                 getJobScheduler().cancel(op.jobId);
             }
         }
@@ -1466,10 +1438,9 @@
 
         // Clean up the storage engine database
         mSyncStorageEngine.doDatabaseCleanup(new Account[0], userId);
-        List<SyncOperation> ops = getAllPendingSyncsFromCache();
+        List<SyncOperation> ops = getAllPendingSyncs();
         for (SyncOperation op: ops) {
             if (op.target.userId == userId) {
-                removeSyncOperationFromCache(op.jobId);
                 getJobScheduler().cancel(op.jobId);
             }
         }
@@ -1635,7 +1606,7 @@
 
     protected void dumpPendingSyncs(PrintWriter pw) {
         pw.println("Pending Syncs:");
-        List<SyncOperation> pendingSyncs = getAllPendingSyncsFromCache();
+        List<SyncOperation> pendingSyncs = getAllPendingSyncs();
         int count = 0;
         for (SyncOperation op: pendingSyncs) {
             if (!op.isPeriodic) {
@@ -1649,7 +1620,7 @@
 
     protected void dumpPeriodicSyncs(PrintWriter pw) {
         pw.println("Periodic Syncs:");
-        List<SyncOperation> pendingSyncs = getAllPendingSyncsFromCache();
+        List<SyncOperation> pendingSyncs = getAllPendingSyncs();
         int count = 0;
         for (SyncOperation op: pendingSyncs) {
             if (op.isPeriodic) {
@@ -2259,10 +2230,6 @@
         private boolean tryEnqueueMessageUntilReadyToRun(Message msg) {
             synchronized (this) {
                 if (!mBootCompleted || !mProvisioned) {
-                    if (msg.what == MESSAGE_START_SYNC) {
-                        SyncOperation op = (SyncOperation) msg.obj;
-                        addSyncOperationToCache(op);
-                    }
                     // Need to copy the message bc looper will recycle it.
                     Message m = Message.obtain(msg);
                     mUnreadyQueue.add(m);
@@ -2479,7 +2446,6 @@
             if (op.isPeriodic) {
                 scheduleSyncOperationH(op.createOneTimeSyncOperation(), delay);
             } else {
-                removeSyncOperationFromCache(op.jobId);
                 scheduleSyncOperationH(op, delay);
             }
         }
@@ -2489,7 +2455,6 @@
             if (op.isPeriodic) {
                 scheduleSyncOperationH(op.createOneTimeSyncOperation(), delay);
             } else {
-                removeSyncOperationFromCache(op.jobId);
                 scheduleSyncOperationH(op, delay);
             }
         }
@@ -2515,7 +2480,7 @@
             if (op.isPeriodic) {
                 // Don't allow this periodic to run if a previous instance failed and is currently
                 // scheduled according to some backoff criteria.
-                List<SyncOperation> ops = getAllPendingSyncsFromCache();
+                List<SyncOperation> ops = getAllPendingSyncs();
                 for (SyncOperation syncOperation: ops) {
                     if (syncOperation.sourcePeriodicId == op.jobId) {
                         mSyncJobService.callJobFinished(op.jobId, false);
@@ -2535,9 +2500,6 @@
                     deferSyncH(op, 0 /* No minimum delay */);
                     return;
                 }
-            } else {
-                // Remove SyncOperation entry from mScheduledSyncs cache for non periodic jobs.
-                removeSyncOperationFromCache(op.jobId);
             }
 
             // Check for conflicting syncs.
@@ -2616,10 +2578,9 @@
                 }
             }
 
-            List<SyncOperation> ops = getAllPendingSyncsFromCache();
+            List<SyncOperation> ops = getAllPendingSyncs();
             for (SyncOperation op: ops) {
                 if (!containsAccountAndUser(accounts, op.target.account, op.target.userId)) {
-                    removeSyncOperationFromCache(op.jobId);
                     getJobScheduler().cancel(op.jobId);
                 }
             }
@@ -2665,7 +2626,7 @@
                         + " flexMillis: " + flex
                         + " extras: " + extras.toString());
             }
-            List<SyncOperation> ops = getAllPendingSyncsFromCache();
+            List<SyncOperation> ops = getAllPendingSyncs();
             for (SyncOperation op: ops) {
                 if (op.isPeriodic && op.target.matchesSpec(target)
                         && syncExtrasEquals(op.extras, extras, true /* includeSyncSettings */)) {
@@ -2704,7 +2665,7 @@
          */
         private void removePeriodicSyncInternalH(SyncOperation syncOperation) {
             // Remove this periodic sync and all one-off syncs initiated by it.
-            List<SyncOperation> ops = getAllPendingSyncsFromCache();
+            List<SyncOperation> ops = getAllPendingSyncs();
             for (SyncOperation op: ops) {
                 if (op.sourcePeriodicId == syncOperation.jobId || op.jobId == syncOperation.jobId) {
                     ActiveSyncContext asc = findActiveSyncContextH(syncOperation.jobId);
@@ -2712,7 +2673,6 @@
                         mSyncJobService.callJobFinished(syncOperation.jobId, false);
                         runSyncFinishedOrCanceledH(null, asc);
                     }
-                    removeSyncOperationFromCache(op.jobId);
                     getJobScheduler().cancel(op.jobId);
                 }
             }
@@ -2720,7 +2680,7 @@
 
         private void removePeriodicSyncH(EndPoint target, Bundle extras) {
             verifyJobScheduler();
-            List<SyncOperation> ops = getAllPendingSyncsFromCache();
+            List<SyncOperation> ops = getAllPendingSyncs();
             for (SyncOperation op: ops) {
                 if (op.isPeriodic && op.target.matchesSpec(target)
                         && syncExtrasEquals(op.extras, extras, true /* includeSyncSettings */)) {
@@ -2896,7 +2856,7 @@
         private void reschedulePeriodicSyncH(SyncOperation syncOperation) {
             // Ensure that the periodic sync wasn't removed.
             SyncOperation periodicSync = null;
-            List<SyncOperation> ops = getAllPendingSyncsFromCache();
+            List<SyncOperation> ops = getAllPendingSyncs();
             for (SyncOperation op: ops) {
                 if (op.isPeriodic && syncOperation.matchesPeriodicOperation(op)) {
                     periodicSync = op;
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 088d96e..4527f1f 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -381,8 +381,8 @@
                             | DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS;
                 }
 
+                final Resources res = getContext().getResources();
                 if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
-                    final Resources res = getContext().getResources();
                     mInfo.name = res.getString(
                             com.android.internal.R.string.display_manager_built_in_display_name);
                     mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
@@ -416,6 +416,11 @@
                     if (SystemProperties.getBoolean("persist.demo.hdmirotates", false)) {
                         mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
                     }
+
+                    if (!res.getBoolean(
+                                com.android.internal.R.bool.config_localDisplaysMirrorContent)) {
+                        mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY;
+                    }
                 }
             }
             return mInfo;
diff --git a/services/core/java/com/android/server/job/JobSchedulerInternal.java b/services/core/java/com/android/server/job/JobSchedulerInternal.java
new file mode 100644
index 0000000..75170ec
--- /dev/null
+++ b/services/core/java/com/android/server/job/JobSchedulerInternal.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 The Android Open Source 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.job;
+
+import android.app.job.JobInfo;
+
+import java.util.List;
+
+/**
+ * JobScheduler local system service interface.
+ * {@hide} Only for use within the system server.
+ */
+public interface JobSchedulerInternal {
+
+    /**
+     * Returns a list of pending jobs scheduled by the system service.
+     */
+    List<JobInfo> getSystemScheduledPendingJobs();
+}
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index d2b77aa..cee46195 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -45,6 +45,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Process;
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
@@ -505,6 +506,7 @@
 
     @Override
     public void onStart() {
+        publishLocalService(JobSchedulerInternal.class, new LocalService());
         publishBinderService(Context.JOB_SCHEDULER_SERVICE, mJobSchedulerStub);
     }
 
@@ -1178,6 +1180,28 @@
         return -1;
     }
 
+    final class LocalService implements JobSchedulerInternal {
+
+        /**
+         * Returns a list of all pending jobs. A running job is not considered pending. Periodic
+         * jobs are always considered pending.
+         */
+        public List<JobInfo> getSystemScheduledPendingJobs() {
+            synchronized (mLock) {
+                final List<JobInfo> pendingJobs = new ArrayList<JobInfo>();
+                mJobs.forEachJob(Process.SYSTEM_UID, new JobStatusFunctor() {
+                    @Override
+                    public void process(JobStatus job) {
+                        if (job.getJob().isPeriodic() || !isCurrentlyActiveLocked(job)) {
+                            pendingJobs.add(job.getJob());
+                        }
+                    }
+                });
+                return pendingJobs;
+            }
+        }
+    }
+
     /**
      * Binder stub trampoline implementation
      */
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index 9837a56..55f37b8 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -210,6 +210,10 @@
         mJobSet.forEachJob(functor);
     }
 
+    public void forEachJob(int uid, JobStatusFunctor functor) {
+        mJobSet.forEachJob(uid, functor);
+    }
+
     public interface JobStatusFunctor {
         public void process(JobStatus jobStatus);
     }
@@ -870,5 +874,14 @@
                 }
             }
         }
+
+        public void forEachJob(int uid, JobStatusFunctor functor) {
+            ArraySet<JobStatus> jobs = mJobs.get(uid);
+            if (jobs != null) {
+                for (int i = jobs.size() - 1; i >= 0; i--) {
+                    functor.process(jobs.valueAt(i));
+                }
+            }
+        }
     }
 }
diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
index bd06645..6ef425a 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -185,7 +185,7 @@
         pw.println("Conn.");
         pw.println("connected: " + mNetworkConnected + " unmetered: " + mNetworkUnmetered);
         for (JobStatus js: mTrackedJobs) {
-            pw.println(String.valueOf(js.hashCode()).substring(0, 3) + ".."
+            pw.println(String.valueOf(js.getJobId() + "," + js.getUid())
                     + ": C=" + js.hasConnectivityConstraint()
                     + ", UM=" + js.hasUnmeteredConstraint());
         }
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 7638494..d9eb45c 100644
--- a/services/core/java/com/android/server/job/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -197,7 +197,7 @@
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             final JobStatus js = mTrackedTasks.get(i);
             pw.print("  ");
-            pw.print(String.valueOf(js.hashCode()).substring(0, 3));
+            pw.print(String.valueOf(js.getJobId() + "," + js.getUid()));
             pw.println("..");
         }
     }
diff --git a/services/core/java/com/android/server/job/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java
index 620800c..36fa9ec 100644
--- a/services/core/java/com/android/server/job/controllers/TimeController.java
+++ b/services/core/java/com/android/server/job/controllers/TimeController.java
@@ -145,6 +145,9 @@
                 final long jobDeadline = job.getLatestRunTimeElapsed();
 
                 if (jobDeadline <= nowElapsedMillis) {
+                    if (job.hasTimingDelayConstraint()) {
+                        job.setTimingDelayConstraintSatisfied(true);
+                    }
                     job.setDeadlineConstraintSatisfied(true);
                     mStateChangedListener.onRunJobNow(job);
                     it.remove();
@@ -281,7 +284,7 @@
                 + "s");
         pw.println("Tracking:");
         for (JobStatus ts : mTrackedJobs) {
-            pw.println(String.valueOf(ts.hashCode()).substring(0, 3) + ".."
+            pw.println(String.valueOf(ts.getJobId() + "," + ts.getUid())
                     + ": (" + (ts.hasTimingDelayConstraint() ? ts.getEarliestRunTime() : "N/A")
                     + ", " + (ts.hasDeadlineConstraint() ?ts.getLatestRunTimeElapsed() : "N/A")
                     + ")");
diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java
index d986e94b..673dd8f 100644
--- a/services/core/java/com/android/server/net/NetworkStatsCollection.java
+++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java
@@ -17,8 +17,8 @@
 package com.android.server.net;
 
 import static android.net.NetworkStats.IFACE_ALL;
-import static android.net.NetworkStats.ROAMING_DEFAULT;
-import static android.net.NetworkStats.ROAMING_ROAMING;
+import static android.net.NetworkStats.ROAMING_NO;
+import static android.net.NetworkStats.ROAMING_YES;
 import static android.net.NetworkStats.SET_ALL;
 import static android.net.NetworkStats.SET_DEFAULT;
 import static android.net.NetworkStats.TAG_NONE;
@@ -242,7 +242,7 @@
                 entry.uid = key.uid;
                 entry.set = key.set;
                 entry.tag = key.tag;
-                entry.roaming = key.ident.isAnyMemberRoaming() ? ROAMING_ROAMING : ROAMING_DEFAULT;
+                entry.roaming = key.ident.isAnyMemberRoaming() ? ROAMING_YES : ROAMING_NO;
                 entry.rxBytes = historyEntry.rxBytes;
                 entry.rxPackets = historyEntry.rxPackets;
                 entry.txBytes = historyEntry.txBytes;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 516602e..1413117 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -43,6 +43,7 @@
 import static org.xmlpull.v1.XmlPullParser.START_TAG;
 
 import android.Manifest;
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
@@ -218,7 +219,7 @@
     private IActivityManager mAm;
     AudioManager mAudioManager;
     AudioManagerInternal mAudioManagerInternal;
-    StatusBarManagerInternal mStatusBar;
+    @Nullable StatusBarManagerInternal mStatusBar;
     Vibrator mVibrator;
     private VrManagerInternal mVrManagerInternal;
 
@@ -795,7 +796,9 @@
             } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
                 // turn off LED when user passes through lock screen
                 mNotificationLight.turnOff();
-                mStatusBar.notificationLightOff();
+                if (mStatusBar != null) {
+                    mStatusBar.notificationLightOff();
+                }
             } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
                 final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
                 // reload per-user settings
@@ -859,7 +862,9 @@
     private final Runnable mBuzzBeepBlinked = new Runnable() {
         @Override
         public void run() {
-            mStatusBar.buzzBeepBlinked();
+            if (mStatusBar != null) {
+                mStatusBar.buzzBeepBlinked();
+            }
         }
     };
 
@@ -958,7 +963,9 @@
         }
 
         mStatusBar = getLocalService(StatusBarManagerInternal.class);
-        mStatusBar.setNotificationDelegate(mNotificationDelegate);
+        if (mStatusBar != null) {
+            mStatusBar.setNotificationDelegate(mNotificationDelegate);
+        }
 
         final LightsManager lights = getLocalService(LightsManager.class);
         mNotificationLight = lights.getLight(LightsManager.LIGHT_ID_NOTIFICATIONS);
@@ -3301,7 +3308,9 @@
         // Don't flash while we are in a call or screen is on
         if (ledNotification == null || mInCall || mScreenOn) {
             mNotificationLight.turnOff();
-            mStatusBar.notificationLightOff();
+            if (mStatusBar != null) {
+                mStatusBar.notificationLightOff();
+            }
         } else {
             final Notification ledno = ledNotification.sbn.getNotification();
             int ledARGB = ledno.ledARGB;
@@ -3317,8 +3326,10 @@
                 mNotificationLight.setFlashing(ledARGB, Light.LIGHT_FLASH_TIMED,
                         ledOnMS, ledOffMS);
             }
-            // let SystemUI make an independent decision
-            mStatusBar.notificationLightPulse(ledARGB, ledOnMS, ledOffMS);
+            if (mStatusBar != null) {
+                // let SystemUI make an independent decision
+                mStatusBar.notificationLightPulse(ledARGB, ledOnMS, ledOffMS);
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java
index 538f951..b853417 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -336,6 +336,13 @@
             finalImportance = new ImportanceHistogram(context, "note_importance_");
         }
 
+        public AggregatedStats getPrevious() {
+            if (mPrevious == null) {
+                mPrevious = new AggregatedStats(mContext, key);
+            }
+            return mPrevious;
+        }
+
         public void countApiUse(NotificationRecord record) {
             final Notification n = record.getNotification();
             if (n.actions != null) {
@@ -411,67 +418,64 @@
         }
 
         public void emit() {
-            if (mPrevious == null) {
-                mPrevious = new AggregatedStats(null, key);
-            }
+            AggregatedStats previous = getPrevious();
+            maybeCount("note_post", (numPostedByApp - previous.numPostedByApp));
+            maybeCount("note_update", (numUpdatedByApp - previous.numUpdatedByApp));
+            maybeCount("note_remove", (numRemovedByApp - previous.numRemovedByApp));
+            maybeCount("note_with_people", (numWithValidPeople - previous.numWithValidPeople));
+            maybeCount("note_with_stars", (numWithStaredPeople - previous.numWithStaredPeople));
+            maybeCount("people_cache_hit", (numPeopleCacheHit - previous.numPeopleCacheHit));
+            maybeCount("people_cache_miss", (numPeopleCacheMiss - previous.numPeopleCacheMiss));
+            maybeCount("note_blocked", (numBlocked - previous.numBlocked));
+            maybeCount("note_suspended", (numSuspendedByAdmin - previous.numSuspendedByAdmin));
+            maybeCount("note_with_actions", (numWithActions - previous.numWithActions));
+            maybeCount("note_private", (numPrivate - previous.numPrivate));
+            maybeCount("note_secret", (numSecret - previous.numSecret));
+            maybeCount("note_interupt", (numInterrupt - previous.numInterrupt));
+            maybeCount("note_big_text", (numWithBigText - previous.numWithBigText));
+            maybeCount("note_big_pic", (numWithBigPicture - previous.numWithBigPicture));
+            maybeCount("note_fg", (numForegroundService - previous.numForegroundService));
+            maybeCount("note_ongoing", (numOngoing - previous.numOngoing));
+            maybeCount("note_auto", (numAutoCancel - previous.numAutoCancel));
+            maybeCount("note_large_icon", (numWithLargeIcon - previous.numWithLargeIcon));
+            maybeCount("note_inbox", (numWithInbox - previous.numWithInbox));
+            maybeCount("note_media", (numWithMediaSession - previous.numWithMediaSession));
+            maybeCount("note_title", (numWithTitle - previous.numWithTitle));
+            maybeCount("note_text", (numWithText - previous.numWithText));
+            maybeCount("note_sub_text", (numWithSubText - previous.numWithSubText));
+            maybeCount("note_info_text", (numWithInfoText - previous.numWithInfoText));
+            noisyImportance.maybeCount(previous.noisyImportance);
+            quietImportance.maybeCount(previous.quietImportance);
+            finalImportance.maybeCount(previous.finalImportance);
 
-            maybeCount("note_post", (numPostedByApp - mPrevious.numPostedByApp));
-            maybeCount("note_update", (numUpdatedByApp - mPrevious.numUpdatedByApp));
-            maybeCount("note_remove", (numRemovedByApp - mPrevious.numRemovedByApp));
-            maybeCount("note_with_people", (numWithValidPeople - mPrevious.numWithValidPeople));
-            maybeCount("note_with_stars", (numWithStaredPeople - mPrevious.numWithStaredPeople));
-            maybeCount("people_cache_hit", (numPeopleCacheHit - mPrevious.numPeopleCacheHit));
-            maybeCount("people_cache_miss", (numPeopleCacheMiss - mPrevious.numPeopleCacheMiss));
-            maybeCount("note_blocked", (numBlocked - mPrevious.numBlocked));
-            maybeCount("note_suspended", (numSuspendedByAdmin - mPrevious.numSuspendedByAdmin));
-            maybeCount("note_with_actions", (numWithActions - mPrevious.numWithActions));
-            maybeCount("note_private", (numPrivate - mPrevious.numPrivate));
-            maybeCount("note_secret", (numSecret - mPrevious.numSecret));
-            maybeCount("note_interupt", (numInterrupt - mPrevious.numInterrupt));
-            maybeCount("note_big_text", (numWithBigText - mPrevious.numWithBigText));
-            maybeCount("note_big_pic", (numWithBigPicture - mPrevious.numWithBigPicture));
-            maybeCount("note_fg", (numForegroundService - mPrevious.numForegroundService));
-            maybeCount("note_ongoing", (numOngoing - mPrevious.numOngoing));
-            maybeCount("note_auto", (numAutoCancel - mPrevious.numAutoCancel));
-            maybeCount("note_large_icon", (numWithLargeIcon - mPrevious.numWithLargeIcon));
-            maybeCount("note_inbox", (numWithInbox - mPrevious.numWithInbox));
-            maybeCount("note_media", (numWithMediaSession - mPrevious.numWithMediaSession));
-            maybeCount("note_title", (numWithTitle - mPrevious.numWithTitle));
-            maybeCount("note_text", (numWithText - mPrevious.numWithText));
-            maybeCount("note_sub_text", (numWithSubText - mPrevious.numWithSubText));
-            maybeCount("note_info_text", (numWithInfoText - mPrevious.numWithInfoText));
-            noisyImportance.maybeCount(mPrevious.noisyImportance);
-            quietImportance.maybeCount(mPrevious.quietImportance);
-            finalImportance.maybeCount(mPrevious.finalImportance);
-
-            mPrevious.numPostedByApp = numPostedByApp;
-            mPrevious.numUpdatedByApp = numUpdatedByApp;
-            mPrevious.numRemovedByApp = numRemovedByApp;
-            mPrevious.numPeopleCacheHit = numPeopleCacheHit;
-            mPrevious.numPeopleCacheMiss = numPeopleCacheMiss;
-            mPrevious.numWithStaredPeople = numWithStaredPeople;
-            mPrevious.numWithValidPeople = numWithValidPeople;
-            mPrevious.numBlocked = numBlocked;
-            mPrevious.numSuspendedByAdmin = numSuspendedByAdmin;
-            mPrevious.numWithActions = numWithActions;
-            mPrevious.numPrivate = numPrivate;
-            mPrevious.numSecret = numSecret;
-            mPrevious.numInterrupt = numInterrupt;
-            mPrevious.numWithBigText = numWithBigText;
-            mPrevious.numWithBigPicture = numWithBigPicture;
-            mPrevious.numForegroundService = numForegroundService;
-            mPrevious.numOngoing = numOngoing;
-            mPrevious.numAutoCancel = numAutoCancel;
-            mPrevious.numWithLargeIcon = numWithLargeIcon;
-            mPrevious.numWithInbox = numWithInbox;
-            mPrevious.numWithMediaSession = numWithMediaSession;
-            mPrevious.numWithTitle = numWithTitle;
-            mPrevious.numWithText = numWithText;
-            mPrevious.numWithSubText = numWithSubText;
-            mPrevious.numWithInfoText = numWithInfoText;
-            noisyImportance.update(mPrevious.noisyImportance);
-            quietImportance.update(mPrevious.quietImportance);
-            finalImportance.update(mPrevious.finalImportance);
+            previous.numPostedByApp = numPostedByApp;
+            previous.numUpdatedByApp = numUpdatedByApp;
+            previous.numRemovedByApp = numRemovedByApp;
+            previous.numPeopleCacheHit = numPeopleCacheHit;
+            previous.numPeopleCacheMiss = numPeopleCacheMiss;
+            previous.numWithStaredPeople = numWithStaredPeople;
+            previous.numWithValidPeople = numWithValidPeople;
+            previous.numBlocked = numBlocked;
+            previous.numSuspendedByAdmin = numSuspendedByAdmin;
+            previous.numWithActions = numWithActions;
+            previous.numPrivate = numPrivate;
+            previous.numSecret = numSecret;
+            previous.numInterrupt = numInterrupt;
+            previous.numWithBigText = numWithBigText;
+            previous.numWithBigPicture = numWithBigPicture;
+            previous.numForegroundService = numForegroundService;
+            previous.numOngoing = numOngoing;
+            previous.numAutoCancel = numAutoCancel;
+            previous.numWithLargeIcon = numWithLargeIcon;
+            previous.numWithInbox = numWithInbox;
+            previous.numWithMediaSession = numWithMediaSession;
+            previous.numWithTitle = numWithTitle;
+            previous.numWithText = numWithText;
+            previous.numWithSubText = numWithSubText;
+            previous.numWithInfoText = numWithInfoText;
+            noisyImportance.update(previous.noisyImportance);
+            quietImportance.update(previous.quietImportance);
+            finalImportance.update(previous.finalImportance);
         }
 
         void maybeCount(String name, int value) {
@@ -553,6 +557,7 @@
         }
 
         public JSONObject dumpJson() throws JSONException {
+            AggregatedStats previous = getPrevious();
             JSONObject dump = new JSONObject();
             dump.put("key", key);
             dump.put("duration", SystemClock.elapsedRealtime() - mCreated);
@@ -581,9 +586,9 @@
             maybePut(dump, "numWithText", numWithText);
             maybePut(dump, "numWithSubText", numWithSubText);
             maybePut(dump, "numWithInfoText", numWithInfoText);
-            noisyImportance.maybePut(dump, mPrevious.noisyImportance);
-            quietImportance.maybePut(dump, mPrevious.quietImportance);
-            finalImportance.maybePut(dump, mPrevious.finalImportance);
+            noisyImportance.maybePut(dump, previous.noisyImportance);
+            quietImportance.maybePut(dump, previous.quietImportance);
+            finalImportance.maybePut(dump, previous.finalImportance);
 
             return dump;
         }
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index b7cd318..5b0ceca 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -28,6 +28,7 @@
 import android.content.pm.ILauncherApps;
 import android.content.pm.IOnAppsChangedListener;
 import android.content.pm.IPackageManager;
+import android.content.pm.LauncherApps.ShortcutQuery;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -74,9 +75,20 @@
 
     @Override
     public void onStart() {
+        Binder.LOG_RUNTIME_EXCEPTION = true;
         publishBinderService(Context.LAUNCHER_APPS_SERVICE, mLauncherAppsImpl);
     }
 
+    static class BroadcastCookie {
+        public final UserHandle user;
+        public final String packageName;
+
+        BroadcastCookie(UserHandle userHandle, String packageName) {
+            this.user = userHandle;
+            this.packageName = packageName;
+        }
+    }
+
     @VisibleForTesting
     static class LauncherAppsImpl extends ILauncherApps.Stub {
         private static final boolean DEBUG = false;
@@ -99,12 +111,22 @@
             mShortcutServiceInternal.addListener(mPackageMonitor);
         }
 
+        @VisibleForTesting
+        int injectBinderCallingUid() {
+            return getCallingUid();
+        }
+
+        private int getCallingUserId() {
+            return UserHandle.getUserId(injectBinderCallingUid());
+        }
+
         /*
          * @see android.content.pm.ILauncherApps#addOnAppsChangedListener(
          *          android.content.pm.IOnAppsChangedListener)
          */
         @Override
-        public void addOnAppsChangedListener(IOnAppsChangedListener listener) throws RemoteException {
+        public void addOnAppsChangedListener(String callingPackage, IOnAppsChangedListener listener)
+                throws RemoteException {
             synchronized (mListeners) {
                 if (DEBUG) {
                     Log.d(TAG, "Adding listener from " + Binder.getCallingUserHandle());
@@ -116,7 +138,8 @@
                     startWatchingPackageBroadcasts();
                 }
                 mListeners.unregister(listener);
-                mListeners.register(listener, Binder.getCallingUserHandle());
+                mListeners.register(listener, new BroadcastCookie(UserHandle.of(getCallingUserId()),
+                        callingPackage));
             }
         }
 
@@ -296,17 +319,21 @@
             }
         }
 
-        private void enforceShortcutPermission(UserHandle user) {
+        private void ensureShortcutPermission(@NonNull String callingPackage, UserHandle user) {
+            verifyCallingPackage(callingPackage);
             ensureInUserProfiles(user, "Cannot start activity for unrelated profile " + user);
-            // STOPSHIP Implement it
+
+            if (!mShortcutServiceInternal.hasShortcutHostPermission(callingPackage,
+                    user.getIdentifier())) {
+                throw new SecurityException("Caller can't access shortcut information");
+            }
         }
 
         @Override
         public ParceledListSlice getShortcuts(String callingPackage, long changedSince,
                 String packageName, ComponentName componentName, int flags, UserHandle user)
                 throws RemoteException {
-            enforceShortcutPermission(user);
-            verifyCallingPackage(callingPackage);
+            ensureShortcutPermission(callingPackage, user);
 
             return new ParceledListSlice<>(
                     mShortcutServiceInternal.getShortcuts(callingPackage, changedSince, packageName,
@@ -316,8 +343,7 @@
         @Override
         public ParceledListSlice getShortcutInfo(String callingPackage, String packageName,
                 List<String> ids, UserHandle user) throws RemoteException {
-            enforceShortcutPermission(user);
-            verifyCallingPackage(callingPackage);
+            ensureShortcutPermission(callingPackage, user);
 
             return new ParceledListSlice<>(
                     mShortcutServiceInternal.getShortcutInfo(callingPackage, packageName,
@@ -327,8 +353,7 @@
         @Override
         public void pinShortcuts(String callingPackage, String packageName, List<String> ids,
                 UserHandle user) throws RemoteException {
-            enforceShortcutPermission(user);
-            verifyCallingPackage(callingPackage);
+            ensureShortcutPermission(callingPackage, user);
 
             mShortcutServiceInternal.pinShortcuts(callingPackage, packageName,
                     ids, user.getIdentifier());
@@ -337,8 +362,7 @@
         @Override
         public int getShortcutIconResId(String callingPackage, ShortcutInfo shortcut,
                 UserHandle user) {
-            enforceShortcutPermission(user);
-            verifyCallingPackage(callingPackage);
+            ensureShortcutPermission(callingPackage, user);
 
             return mShortcutServiceInternal.getShortcutIconResId(callingPackage, shortcut,
                     user.getIdentifier());
@@ -347,19 +371,24 @@
         @Override
         public ParcelFileDescriptor getShortcutIconFd(String callingPackage, ShortcutInfo shortcut,
                 UserHandle user) {
-            enforceShortcutPermission(user);
-            verifyCallingPackage(callingPackage);
+            ensureShortcutPermission(callingPackage, user);
 
             return mShortcutServiceInternal.getShortcutIconFd(callingPackage, shortcut,
                     user.getIdentifier());
         }
 
         @Override
+        public boolean hasShortcutHostPermission(String callingPackage) throws RemoteException {
+            verifyCallingPackage(callingPackage);
+            return mShortcutServiceInternal.hasShortcutHostPermission(callingPackage,
+                    getCallingUserId());
+        }
+
+        @Override
         public boolean startShortcut(String callingPackage, String packageName, String shortcutId,
                 Rect sourceBounds, Bundle startActivityOptions, UserHandle user)
                 throws RemoteException {
-            enforceShortcutPermission(user);
-            verifyCallingPackage(callingPackage);
+            ensureShortcutPermission(callingPackage, user);
 
             final Intent intent = mShortcutServiceInternal.createShortcutIntent(callingPackage,
                     packageName, shortcutId, user.getIdentifier());
@@ -475,41 +504,44 @@
             }
         }
 
-
-        private class MyPackageMonitor extends PackageMonitor implements ShortcutChangeListener {
-
-            /** Checks if user is a profile of or same as listeningUser.
-              * and the user is enabled. */
-            private boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser,
-                    String debugMsg) {
-                if (user.getIdentifier() == listeningUser.getIdentifier()) {
-                    if (DEBUG) Log.d(TAG, "Delivering msg to same user " + debugMsg);
+        /** Checks if user is a profile of or same as listeningUser.
+         * and the user is enabled. */
+        boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser,
+                String debugMsg) {
+            if (user.getIdentifier() == listeningUser.getIdentifier()) {
+                if (DEBUG) Log.d(TAG, "Delivering msg to same user " + debugMsg);
+                return true;
+            }
+            long ident = Binder.clearCallingIdentity();
+            try {
+                UserInfo userInfo = mUm.getUserInfo(user.getIdentifier());
+                UserInfo listeningUserInfo = mUm.getUserInfo(listeningUser.getIdentifier());
+                if (userInfo == null || listeningUserInfo == null
+                        || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID
+                        || userInfo.profileGroupId != listeningUserInfo.profileGroupId
+                        || !userInfo.isEnabled()) {
+                    if (DEBUG) {
+                        Log.d(TAG, "Not delivering msg from " + user + " to " + listeningUser + ":"
+                                + debugMsg);
+                    }
+                    return false;
+                } else {
+                    if (DEBUG) {
+                        Log.d(TAG, "Delivering msg from " + user + " to " + listeningUser + ":"
+                                + debugMsg);
+                    }
                     return true;
                 }
-                long ident = Binder.clearCallingIdentity();
-                try {
-                    UserInfo userInfo = mUm.getUserInfo(user.getIdentifier());
-                    UserInfo listeningUserInfo = mUm.getUserInfo(listeningUser.getIdentifier());
-                    if (userInfo == null || listeningUserInfo == null
-                            || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID
-                            || userInfo.profileGroupId != listeningUserInfo.profileGroupId
-                            || !userInfo.isEnabled()) {
-                        if (DEBUG) {
-                            Log.d(TAG, "Not delivering msg from " + user + " to " + listeningUser + ":"
-                                    + debugMsg);
-                        }
-                        return false;
-                    } else {
-                        if (DEBUG) {
-                            Log.d(TAG, "Delivering msg from " + user + " to " + listeningUser + ":"
-                                    + debugMsg);
-                        }
-                        return true;
-                    }
-                } finally {
-                    Binder.restoreCallingIdentity(ident);
-                }
+            } finally {
+                Binder.restoreCallingIdentity(ident);
             }
+        }
+
+        void postToPackageMonitor(Runnable r) {
+            mPackageMonitor.getRegisteredHandler().post(r);
+        }
+
+        private class MyPackageMonitor extends PackageMonitor implements ShortcutChangeListener {
 
             // TODO Simplify with lambdas.
 
@@ -519,8 +551,8 @@
                 final int n = mListeners.beginBroadcast();
                 for (int i = 0; i < n; i++) {
                     IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
-                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
-                    if (!isEnabledProfileOf(user, listeningUser, "onPackageAdded")) continue;
+                    BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
+                    if (!isEnabledProfileOf(user, cookie.user, "onPackageAdded")) continue;
                     try {
                         listener.onPackageAdded(user, packageName);
                     } catch (RemoteException re) {
@@ -538,8 +570,8 @@
                 final int n = mListeners.beginBroadcast();
                 for (int i = 0; i < n; i++) {
                     IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
-                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
-                    if (!isEnabledProfileOf(user, listeningUser, "onPackageRemoved")) continue;
+                    BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
+                    if (!isEnabledProfileOf(user, cookie.user, "onPackageRemoved")) continue;
                     try {
                         listener.onPackageRemoved(user, packageName);
                     } catch (RemoteException re) {
@@ -557,8 +589,8 @@
                 final int n = mListeners.beginBroadcast();
                 for (int i = 0; i < n; i++) {
                     IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
-                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
-                    if (!isEnabledProfileOf(user, listeningUser, "onPackageModified")) continue;
+                    BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
+                    if (!isEnabledProfileOf(user, cookie.user, "onPackageModified")) continue;
                     try {
                         listener.onPackageChanged(user, packageName);
                     } catch (RemoteException re) {
@@ -576,8 +608,8 @@
                 final int n = mListeners.beginBroadcast();
                 for (int i = 0; i < n; i++) {
                     IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
-                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
-                    if (!isEnabledProfileOf(user, listeningUser, "onPackagesAvailable")) continue;
+                    BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
+                    if (!isEnabledProfileOf(user, cookie.user, "onPackagesAvailable")) continue;
                     try {
                         listener.onPackagesAvailable(user, packages, isReplacing());
                     } catch (RemoteException re) {
@@ -595,8 +627,8 @@
                 final int n = mListeners.beginBroadcast();
                 for (int i = 0; i < n; i++) {
                     IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
-                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
-                    if (!isEnabledProfileOf(user, listeningUser, "onPackagesUnavailable")) continue;
+                    BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
+                    if (!isEnabledProfileOf(user, cookie.user, "onPackagesUnavailable")) continue;
                     try {
                         listener.onPackagesUnavailable(user, packages, isReplacing());
                     } catch (RemoteException re) {
@@ -614,8 +646,8 @@
                 final int n = mListeners.beginBroadcast();
                 for (int i = 0; i < n; i++) {
                     IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
-                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
-                    if (!isEnabledProfileOf(user, listeningUser, "onPackagesSuspended")) continue;
+                    BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
+                    if (!isEnabledProfileOf(user, cookie.user, "onPackagesSuspended")) continue;
                     try {
                         listener.onPackagesSuspended(user, packages);
                     } catch (RemoteException re) {
@@ -633,8 +665,8 @@
                 final int n = mListeners.beginBroadcast();
                 for (int i = 0; i < n; i++) {
                     IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
-                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
-                    if (!isEnabledProfileOf(user, listeningUser, "onPackagesUnsuspended")) continue;
+                    BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
+                    if (!isEnabledProfileOf(user, cookie.user, "onPackagesUnsuspended")) continue;
                     try {
                         listener.onPackagesUnsuspended(user, packages);
                     } catch (RemoteException re) {
@@ -648,17 +680,39 @@
 
             @Override
             public void onShortcutChanged(@NonNull String packageName,
-                    @NonNull List<ShortcutInfo> shortcuts, @UserIdInt int userId) {
+                    @UserIdInt int userId) {
+                postToPackageMonitor(() -> onShortcutChangedInner(packageName, userId));
+            }
+
+            private void onShortcutChangedInner(@NonNull String packageName,
+                    @UserIdInt int userId) {
                 final UserHandle user = UserHandle.of(userId);
 
                 final int n = mListeners.beginBroadcast();
                 for (int i = 0; i < n; i++) {
                     IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
-                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
-                    if (!isEnabledProfileOf(user, listeningUser, "onShortcutChanged")) continue;
+                    BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
+                    if (!isEnabledProfileOf(user, cookie.user, "onShortcutChanged")) continue;
+
+                    // Make sure the caller has the permission.
+                    if (!mShortcutServiceInternal.hasShortcutHostPermission(cookie.packageName,
+                            cookie.user.getIdentifier())) {
+                        continue;
+                    }
+                    // Each launcher has a different set of pinned shortcuts, so we need to do a
+                    // query in here.
+                    // (As of now, only one launcher has the permission at a time, so it's bit
+                    // moot, but we may change the permission model eventually.)
+                    final List<ShortcutInfo> list =
+                            mShortcutServiceInternal.getShortcuts(cookie.packageName,
+                            /* changedSince= */ 0, packageName, /* component= */ null,
+                                    ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY
+                                    | ShortcutQuery.FLAG_GET_PINNED
+                                    | ShortcutQuery.FLAG_GET_DYNAMIC
+                                    , userId);
                     try {
                         listener.onShortcutChanged(user, packageName,
-                                new ParceledListSlice<>(shortcuts));
+                                new ParceledListSlice<>(list));
                     } catch (RemoteException re) {
                         Slog.d(TAG, "Callback failed ", re);
                     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index debe072..b624087 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -6891,7 +6891,8 @@
 
         // Extract pacakges only if profile-guided compilation is enabled because
         // otherwise BackgroundDexOptService will not dexopt them later.
-        if (!isUpgrade()) {
+        boolean prunedCache = VMRuntime.didPruneDalvikCache();
+        if (!isUpgrade() && !prunedCache) {
             return;
         }
 
@@ -6919,8 +6920,11 @@
             }
 
             if (PackageDexOptimizer.canOptimizePackage(pkg)) {
+                // If the cache was pruned, any compiled odex files will likely be out of date
+                // and would have to be patched (would be SELF_PATCHOAT, which is deprecated).
+                // Instead, force the extraction in this case.
                 performDexOpt(pkg.packageName, null /* instructionSet */,
-                         false /* useProfiles */, true /* extractOnly */, false /* force */);
+                         false /* useProfiles */, true /* extractOnly */, prunedCache);
             }
         }
     }
@@ -10822,25 +10826,41 @@
         }
     }
 
-    // TODO: investigate and add more restrictions for suspending crucial packages.
+    /**
+     * TODO: cache and disallow blocking the active dialer.
+     *
+     * @see also DefaultPermissionGrantPolicy#grantDefaultSystemHandlerPermissions
+     */
     private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
         if (isPackageDeviceAdmin(packageName, userId)) {
-            Slog.w(TAG, "Not suspending/un-suspending package \"" + packageName
-                    + "\": has active device admin");
+            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
+                    + "\": has an active device admin");
             return false;
         }
 
         String activeLauncherPackageName = getActiveLauncherPackageName(userId);
         if (packageName.equals(activeLauncherPackageName)) {
-            Slog.w(TAG, "Not suspending/un-suspending package \"" + packageName
-                    + "\" because it is set as the active launcher");
+            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
+                    + "\": contains the active launcher");
+            return false;
+        }
+
+        if (packageName.equals(mRequiredInstallerPackage)) {
+            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
+                    + "\": required for package installation");
+            return false;
+        }
+
+        if (packageName.equals(mRequiredVerifierPackage)) {
+            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
+                    + "\": required for package verification");
             return false;
         }
 
         final PackageParser.Package pkg = mPackages.get(packageName);
         if (pkg != null && isPrivilegedApp(pkg)) {
-            Slog.w(TAG, "Not suspending/un-suspending package \"" + packageName
-                    + "\" because it is a privileged app");
+            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
+                    + "\": is a privileged app");
             return false;
         }
 
@@ -16436,14 +16456,17 @@
 
     @Override
     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
+        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
+    }
+
+    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
+            int userId) {
         Intent intent = new Intent(Intent.ACTION_MAIN);
         intent.addCategory(Intent.CATEGORY_HOME);
-
-        final int callingUserId = UserHandle.getCallingUserId();
         List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
-                PackageManager.GET_META_DATA, callingUserId);
+                PackageManager.GET_META_DATA, userId);
         ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
-                true, false, false, callingUserId);
+                true, false, false, userId);
 
         allHomeCandidates.clear();
         if (list != null) {
@@ -19232,6 +19255,12 @@
         public ApplicationInfo getApplicationInfo(String packageName, int userId) {
             return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
         }
+
+        @Override
+        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
+                int userId) {
+            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 0b0f7ab..0641749 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -28,7 +28,9 @@
 import android.content.pm.LauncherApps.ShortcutQuery;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.ParceledListSlice;
+import android.content.pm.ResolveInfo;
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutServiceInternal;
 import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener;
@@ -71,6 +73,7 @@
 import com.android.server.SystemService;
 
 import libcore.io.IoUtils;
+import libcore.util.Objects;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -88,7 +91,6 @@
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 import java.util.function.Predicate;
 
 /**
@@ -156,6 +158,7 @@
     static final String TAG_INTENT_EXTRAS = "intent-extras";
     static final String TAG_EXTRAS = "extras";
     static final String TAG_SHORTCUT = "shortcut";
+    static final String TAG_LAUNCHER = "launcher";
 
     static final String ATTR_VALUE = "value";
     static final String ATTR_NAME = "name";
@@ -251,10 +254,13 @@
     private CompressFormat mIconPersistFormat;
     private int mIconPersistQuality;
 
+    private final PackageManagerInternal mPackageManagerInternal;
+
     public ShortcutService(Context context) {
         mContext = Preconditions.checkNotNull(context);
         LocalServices.addService(ShortcutServiceInternal.class, new LocalService());
         mHandler = new Handler(BackgroundThread.get().getLooper());
+        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
     }
 
     /**
@@ -460,6 +466,11 @@
         writeTagValue(out, tag, Long.toString(value));
     }
 
+    static void writeTagValue(XmlSerializer out, String tag, ComponentName name) throws IOException {
+        if (name == null) return;
+        writeTagValue(out, tag, name.flattenToString());
+    }
+
     static void writeTagExtra(XmlSerializer out, String tag, PersistableBundle bundle)
             throws IOException, XmlPullParserException {
         if (bundle == null) return;
@@ -658,7 +669,7 @@
     }
 
     // TODO Actually make it async.
-    private void scheduleSaveUser(@UserIdInt int userId) {
+    void scheduleSaveUser(@UserIdInt int userId) {
         synchronized (mLock) {
             saveUserLocked(userId);
         }
@@ -676,6 +687,10 @@
         return mRawLastResetTime + mResetInterval;
     }
 
+    static boolean isClockValid(long time) {
+        return time >= 1420070400; // Thu, 01 Jan 2015 00:00:00 GMT
+    }
+
     /**
      * Update the last reset time.
      */
@@ -690,8 +705,10 @@
             mRawLastResetTime = now;
         } else if (now < mRawLastResetTime) {
             // Clock rewound.
-            // TODO Randomize??
-            mRawLastResetTime = now;
+            if (isClockValid(now)) {
+                // TODO Randomize??
+                mRawLastResetTime = now;
+            }
         } else {
             // TODO Do it properly.
             while ((mRawLastResetTime + mResetInterval) <= now) {
@@ -797,7 +814,7 @@
             return;
         }
 
-        final long token = Binder.clearCallingIdentity();
+        final long token = injectClearCallingIdentity();
         try {
             // Clear icon info on the shortcut.
             shortcut.setIconResourceId(0);
@@ -874,7 +891,7 @@
                 shortcut.clearIcon();
             }
         } finally {
-            Binder.restoreCallingIdentity(token);
+            injectRestoreCallingIdentity(token);
         }
     }
 
@@ -975,6 +992,10 @@
         }
     }
 
+    void postToHandler(Runnable r) {
+        mHandler.post(r);
+    }
+
     /**
      * Throw if {@code numShortcuts} is bigger than {@link #mMaxDynamicShortcuts}.
      */
@@ -994,17 +1015,16 @@
     }
 
     private void notifyListeners(@NonNull String packageName, @UserIdInt int userId) {
-        final ArrayList<ShortcutChangeListener> copy;
-        final List<ShortcutInfo> shortcuts = new ArrayList<>();
-        synchronized (mLock) {
-            copy = new ArrayList<>(mListeners);
-
-            getPackageShortcutsLocked(packageName, userId)
-                    .findAll(shortcuts, /* query =*/ null, ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
-        }
-        for (int i = copy.size() - 1; i >= 0; i--) {
-            copy.get(i).onShortcutChanged(packageName, shortcuts, userId);
-        }
+        postToHandler(() -> {
+            final ArrayList<ShortcutChangeListener> copy;
+            synchronized (mLock) {
+                copy = new ArrayList<>(mListeners);
+            }
+            // Note onShortcutChanged() needs to be called with the system service permissions.
+            for (int i = copy.size() - 1; i >= 0; i--) {
+                copy.get(i).onShortcutChanged(packageName, userId);
+            }
+        });
     }
 
     /**
@@ -1277,18 +1297,98 @@
     public void resetThrottling() {
         enforceSystemOrShell();
 
-        resetThrottlingInner();
+        resetThrottlingInner(getCallingUserId());
     }
 
-    @VisibleForTesting
-    void resetThrottlingInner() {
+    void resetThrottlingInner(@UserIdInt int userId) {
         synchronized (mLock) {
-            mRawLastResetTime = injectCurrentTimeMillis();
+            getUserShortcutsLocked(userId).resetThrottling();
         }
-        scheduleSaveBaseState();
+        scheduleSaveUser(userId);
         Slog.i(TAG, "ShortcutManager: throttling counter reset");
     }
 
+    // We override this method in unit tests to do a simpler check.
+    boolean hasShortcutHostPermission(@NonNull String callingPackage, int userId) {
+        return hasShortcutHostPermissionInner(callingPackage, userId);
+    }
+
+    // This method is extracted so we can directly call this method from unit tests,
+    // even when hasShortcutPermission() is overridden.
+    @VisibleForTesting
+    boolean hasShortcutHostPermissionInner(@NonNull String callingPackage, int userId) {
+        synchronized (mLock) {
+            long start = 0;
+            if (DEBUG) {
+                start = System.currentTimeMillis();
+            }
+
+            final UserShortcuts user = getUserShortcutsLocked(userId);
+
+            final List<ResolveInfo> allHomeCandidates = new ArrayList<>();
+
+            // Default launcher from package manager.
+            final ComponentName defaultLauncher = injectPackageManagerInternal()
+                    .getHomeActivitiesAsUser(allHomeCandidates, userId);
+
+            ComponentName detected;
+            if (defaultLauncher != null) {
+                detected = defaultLauncher;
+                if (DEBUG) {
+                    Slog.v(TAG, "Default launcher from PM: " + detected);
+                }
+            } else {
+                detected = user.getLauncherComponent();
+
+                // TODO: Make sure it's still enabled.
+                if (DEBUG) {
+                    Slog.v(TAG, "Cached launcher: " + detected);
+                }
+            }
+
+            if (detected == null) {
+                // If we reach here, that means it's the first check since the user was created,
+                // and there's already multiple launchers and there's no default set.
+                // Find the system one with the highest priority.
+                // (We need to check the priority too because of FallbackHome in Settings.)
+                // If there's no system launcher yet, then no one can access shortcuts, until
+                // the user explicitly
+                final int size = allHomeCandidates.size();
+
+                int lastPriority = Integer.MIN_VALUE;
+                for (int i = 0; i < size; i++) {
+                    final ResolveInfo ri = allHomeCandidates.get(i);
+                    if (!ri.activityInfo.applicationInfo.isSystemApp()) {
+                        continue;
+                    }
+                    if (DEBUG) {
+                        Slog.d(TAG, String.format("hasShortcutPermissionInner: pkg=%s prio=%d",
+                                ri.activityInfo.getComponentName(), ri.priority));
+                    }
+                    if (ri.priority < lastPriority) {
+                        continue;
+                    }
+                    detected = ri.activityInfo.getComponentName();
+                    lastPriority = ri.priority;
+                }
+            }
+            if (DEBUG) {
+                long end = System.currentTimeMillis();
+                Slog.v(TAG, String.format("hasShortcutPermission took %d ms", end - start));
+            }
+            if (detected != null) {
+                if (DEBUG) {
+                    Slog.v(TAG, "Detected launcher: " + detected);
+                }
+                user.setLauncherComponent(this, detected);
+                return detected.getPackageName().equals(callingPackage);
+            } else {
+                // Default launcher not found.
+                return false;
+            }
+        }
+    }
+
     /**
      * Entry point from {@link LauncherApps}.
      */
@@ -1434,6 +1534,11 @@
                 }
             }
         }
+
+        @Override
+        public boolean hasShortcutHostPermission(@NonNull String callingPackage, int userId) {
+            return ShortcutService.this.hasShortcutHostPermission(callingPackage, userId);
+        }
     }
 
     // === Dump ===
@@ -1512,37 +1617,74 @@
         (new MyShellCommand()).exec(this, in, out, err, args, resultReceiver);
     }
 
+    static class CommandException extends Exception {
+        public CommandException(String message) {
+            super(message);
+        }
+    }
+
     /**
      * Handle "adb shell cmd".
      */
     private class MyShellCommand extends ShellCommand {
+
+        private int mUserId = UserHandle.USER_SYSTEM;
+
+        private void parseOptions(boolean takeUser)
+                throws CommandException {
+            String opt;
+            while ((opt = getNextOption()) != null) {
+                switch (opt) {
+                    case "--user":
+                        if (takeUser) {
+                            mUserId = UserHandle.parseUserArg(getNextArgRequired());
+                            break;
+                        }
+                        // fallthrough
+                    default:
+                        throw new CommandException("Unknown option: " + opt);
+                }
+            }
+        }
+
         @Override
         public int onCommand(String cmd) {
             if (cmd == null) {
                 return handleDefaultCommands(cmd);
             }
             final PrintWriter pw = getOutPrintWriter();
-            int ret = 1;
-            switch (cmd) {
-                case "reset-package-throttling":
-                    ret = handleResetPackageThrottling();
-                    break;
-                case "reset-throttling":
-                    ret = handleResetThrottling();
-                    break;
-                case "override-config":
-                    ret = handleOverrideConfig();
-                    break;
-                case "reset-config":
-                    ret = handleResetConfig();
-                    break;
-                default:
-                    return handleDefaultCommands(cmd);
+            try {
+                switch (cmd) {
+                    case "reset-package-throttling":
+                        handleResetPackageThrottling();
+                        break;
+                    case "reset-throttling":
+                        handleResetThrottling();
+                        break;
+                    case "override-config":
+                        handleOverrideConfig();
+                        break;
+                    case "reset-config":
+                        handleResetConfig();
+                        break;
+                    case "clear-default-launcher":
+                        handleClearDefaultLauncher();
+                        break;
+                    case "get-default-launcher":
+                        handleGetDefaultLauncher();
+                        break;
+                    case "refresh-default-launcher":
+                        handleRefreshDefaultLauncher();
+                        break;
+                    default:
+                        return handleDefaultCommands(cmd);
+                }
+            } catch (CommandException e) {
+                pw.println("Error: " + e.getMessage());
+                return 1;
             }
-            if (ret == 0) {
-                pw.println("Success");
-            }
-            return ret;
+            pw.println("Success");
+            return 0;
         }
 
         @Override
@@ -1562,56 +1704,85 @@
             pw.println("cmd shortcut reset-config");
             pw.println("    Reset the configuration set with \"update-config\"");
             pw.println();
+            pw.println("cmd shortcut clear-default-launcher [--user USER_ID]");
+            pw.println("    Clear the cached default launcher");
+            pw.println();
+            pw.println("cmd shortcut get-default-launcher [--user USER_ID]");
+            pw.println("    Show the cached default launcher");
+            pw.println();
+            pw.println("cmd shortcut refresh-default-launcher [--user USER_ID]");
+            pw.println("    Refresh the cached default launcher");
+            pw.println();
         }
 
-        private int handleResetThrottling() {
-            resetThrottling();
+        private int handleResetThrottling() throws CommandException {
+            parseOptions(/* takeUser =*/ true);
+
+            resetThrottlingInner(mUserId);
             return 0;
         }
 
-        private int handleResetPackageThrottling() {
-            final PrintWriter pw = getOutPrintWriter();
+        private void handleResetPackageThrottling() throws CommandException {
+            parseOptions(/* takeUser =*/ true);
 
-            int userId = UserHandle.USER_SYSTEM;
-            String opt;
-            while ((opt = getNextOption()) != null) {
-                switch (opt) {
-                    case "--user":
-                        userId = UserHandle.parseUserArg(getNextArgRequired());
-                        break;
-                    default:
-                        pw.println("Error: Unknown option: " + opt);
-                        return 1;
-                }
-            }
             final String packageName = getNextArgRequired();
 
             synchronized (mLock) {
-                getPackageShortcutsLocked(packageName, userId).resetRateLimitingForCommandLine();
-                saveUserLocked(userId);
+                getPackageShortcutsLocked(packageName, mUserId).resetRateLimitingForCommandLine();
+                saveUserLocked(mUserId);
             }
-
-            return 0;
         }
 
-        private int handleOverrideConfig() {
-            final PrintWriter pw = getOutPrintWriter();
+        private void handleOverrideConfig() throws CommandException {
             final String config = getNextArgRequired();
 
             synchronized (mLock) {
                 if (!updateConfigurationLocked(config)) {
-                    pw.println("override-config failed.  See logcat for details.");
-                    return 1;
+                    throw new CommandException("override-config failed.  See logcat for details.");
                 }
             }
-            return 0;
         }
 
-        private int handleResetConfig() {
+        private void handleResetConfig() {
             synchronized (mLock) {
                 loadConfigurationLocked();
             }
-            return 0;
+        }
+
+        private void clearLauncher() {
+            synchronized (mLock) {
+                getUserShortcutsLocked(mUserId).setLauncherComponent(
+                        ShortcutService.this, null);
+            }
+        }
+
+        private void showLauncher() {
+            synchronized (mLock) {
+                // This ensures to set the cached launcher.  Package name doesn't matter.
+                hasShortcutHostPermissionInner("-", mUserId);
+
+                getOutPrintWriter().println("Launcher: "
+                        + getUserShortcutsLocked(mUserId).getLauncherComponent());
+            }
+        }
+
+        private void handleClearDefaultLauncher() throws CommandException {
+            parseOptions(/* takeUser =*/ true);
+
+            clearLauncher();
+        }
+
+        private void handleGetDefaultLauncher() throws CommandException {
+            parseOptions(/* takeUser =*/ true);
+
+            showLauncher();
+        }
+
+        private void handleRefreshDefaultLauncher() throws CommandException {
+            parseOptions(/* takeUser =*/ true);
+
+            clearLauncher();
+            showLauncher();
         }
     }
 
@@ -1627,6 +1798,20 @@
         return getCallingUid();
     }
 
+    final int getCallingUserId() {
+        return UserHandle.getUserId(injectBinderCallingUid());
+    }
+
+    // Injection point.
+    long injectClearCallingIdentity() {
+        return Binder.clearCallingIdentity();
+    }
+
+    // Injection point.
+    void injectRestoreCallingIdentity(long token) {
+        Binder.restoreCallingIdentity(token);
+    }
+
     File injectSystemDataPath() {
         return Environment.getDataSystemDirectory();
     }
@@ -1640,6 +1825,10 @@
         return ActivityManager.isLowRamDeviceStatic();
     }
 
+    PackageManagerInternal injectPackageManagerInternal() {
+        return mPackageManagerInternal;
+    }
+
     File getUserBitmapFilePath(@UserIdInt int userId) {
         return new File(injectUserDataPath(userId), DIRECTORY_BITMAPS);
     }
@@ -1687,6 +1876,9 @@
     }
 }
 
+/**
+ * Per-user information.
+ */
 class UserShortcuts {
     private static final String TAG = ShortcutService.TAG;
 
@@ -1695,6 +1887,8 @@
 
     private final ArrayMap<String, PackageShortcuts> mPackages = new ArrayMap<>();
 
+    private ComponentName mLauncherComponent;
+
     public UserShortcuts(int userId) {
         mUserId = userId;
     }
@@ -1706,11 +1900,11 @@
     public void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
         out.startTag(null, ShortcutService.TAG_USER);
 
-        for (int i = 0; i < mPackages.size(); i++) {
-            final String packageName = mPackages.keyAt(i);
-            final PackageShortcuts packageShortcuts = mPackages.valueAt(i);
+        ShortcutService.writeTagValue(out, ShortcutService.TAG_LAUNCHER,
+                mLauncherComponent);
 
-            packageShortcuts.saveToXml(out);
+        for (int i = 0; i < mPackages.size(); i++) {
+            mPackages.valueAt(i).saveToXml(out);
         }
 
         out.endTag(null, ShortcutService.TAG_USER);
@@ -1730,6 +1924,10 @@
             final int depth = parser.getDepth();
             final String tag = parser.getName();
             switch (tag) {
+                case ShortcutService.TAG_LAUNCHER:
+                    ret.mLauncherComponent = ShortcutService.parseComponentNameAttribute(
+                            parser, ShortcutService.ATTR_VALUE);
+                    continue;
                 case ShortcutService.TAG_PACKAGE:
                     final PackageShortcuts shortcuts = PackageShortcuts.loadFromXml(parser, userId);
 
@@ -1742,12 +1940,36 @@
         return ret;
     }
 
+    public ComponentName getLauncherComponent() {
+        return mLauncherComponent;
+    }
+
+    public void setLauncherComponent(ShortcutService s, ComponentName launcherComponent) {
+        if (Objects.equal(mLauncherComponent, launcherComponent)) {
+            return;
+        }
+        mLauncherComponent = launcherComponent;
+        s.scheduleSaveUser(mUserId);
+    }
+
+    public void resetThrottling() {
+        for (int i = mPackages.size() - 1; i >= 0; i--) {
+            mPackages.valueAt(i).resetThrottling();
+        }
+    }
+
     public void dump(@NonNull ShortcutService s, @NonNull PrintWriter pw, @NonNull String prefix) {
-        pw.print("  ");
+        pw.print(prefix);
         pw.print("User: ");
         pw.print(mUserId);
         pw.println();
 
+        pw.print(prefix);
+        pw.print("  ");
+        pw.print("Default launcher: ");
+        pw.print(mLauncherComponent);
+        pw.println();
+
         for (int i = 0; i < mPackages.size(); i++) {
             mPackages.valueAt(i).dump(s, pw, prefix + "  ");
         }
@@ -1791,7 +2013,6 @@
         mPackageName = packageName;
     }
 
-    @GuardedBy("mLock")
     @Nullable
     public ShortcutInfo findShortcutById(String id) {
         return mShortcuts.get(id);
@@ -1818,7 +2039,6 @@
      *
      * It checks the max number of dynamic shortcuts.
      */
-    @GuardedBy("mLock")
     public void updateShortcutWithCapping(@NonNull ShortcutService s,
             @NonNull ShortcutInfo newShortcut) {
         final ShortcutInfo oldShortcut = mShortcuts.get(newShortcut.getId());
@@ -1868,7 +2088,6 @@
         }
     }
 
-    @GuardedBy("mLock")
     public void deleteAllDynamicShortcuts(@NonNull ShortcutService s) {
         for (int i = mShortcuts.size() - 1; i >= 0; i--) {
             mShortcuts.valueAt(i).clearFlags(ShortcutInfo.FLAG_DYNAMIC);
@@ -1877,7 +2096,6 @@
         mDynamicShortcutCount = 0;
     }
 
-    @GuardedBy("mLock")
     public void deleteDynamicWithId(@NonNull ShortcutService s, @NonNull String shortcutId) {
         final ShortcutInfo oldShortcut = mShortcuts.get(shortcutId);
 
@@ -1894,7 +2112,6 @@
         }
     }
 
-    @GuardedBy("mLock")
     public void replacePinned(@NonNull ShortcutService s, String launcherPackage,
             List<String> shortcutIds) {
 
@@ -1919,12 +2136,11 @@
     /**
      * Number of calls that the caller has made, since the last reset.
      */
-    @GuardedBy("mLock")
     public int getApiCallCount(@NonNull ShortcutService s) {
         final long last = s.getLastResetTimeLocked();
 
         final long now = s.injectCurrentTimeMillis();
-        if (mLastResetTime > now) {
+        if (ShortcutService.isClockValid(now) && mLastResetTime > now) {
             // Clock rewound. // TODO Test it
             mLastResetTime = now;
         }
@@ -1941,7 +2157,6 @@
      * If the caller app hasn't been throttled yet, increment {@link #mApiCallCount}
      * and return true.  Otherwise just return false.
      */
-    @GuardedBy("mLock")
     public boolean tryApiCall(@NonNull ShortcutService s) {
         if (getApiCallCount(s) >= s.mMaxDailyUpdates) {
             return false;
@@ -1950,7 +2165,6 @@
         return true;
     }
 
-    @GuardedBy("mLock")
     public void resetRateLimitingForCommandLine() {
         mApiCallCount = 0;
         mLastResetTime = 0;
@@ -1959,7 +2173,6 @@
     /**
      * Find all shortcuts that match {@code query}.
      */
-    @GuardedBy("mLock")
     public void findAll(@NonNull List<ShortcutInfo> result,
             @Nullable Predicate<ShortcutInfo> query, int cloneFlag) {
         for (int i = 0; i < mShortcuts.size(); i++) {
@@ -1970,6 +2183,10 @@
         }
     }
 
+    public void resetThrottling() {
+        mApiCallCount = 0;
+    }
+
     public void dump(@NonNull ShortcutService s, @NonNull PrintWriter pw, @NonNull String prefix) {
         pw.print(prefix);
         pw.print("Package: ");
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 9af1304..0115a08 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -4635,7 +4635,9 @@
         }
 
         // TYPE_SYSTEM_ERROR is above the NavigationBar so it can't be allowed to extend over it.
-        if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0 && attrs.type != TYPE_SYSTEM_ERROR) {
+        // Also, we don't allow windows in multi-window mode to extend out of the screen.
+        if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0 && attrs.type != TYPE_SYSTEM_ERROR
+                && !win.inMultiWindowMode()) {
             df.left = df.top = -10000;
             df.right = df.bottom = 10000;
             if (attrs.type != TYPE_WALLPAPER) {
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index ffdd89a..3cf9590 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -730,13 +730,27 @@
     public void systemRunning() {
         if (DEBUG) Slog.v(TAG, "systemReady");
         WallpaperData wallpaper = mWallpaperMap.get(UserHandle.USER_SYSTEM);
-        // No crop file? Make sure we've finished the processing sequence if necessary
-        if (!wallpaper.cropExists()) {
-            generateCrop(wallpaper);
-        }
-        // Still nothing?  Fall back to default.
-        if (!wallpaper.cropExists()) {
-            clearWallpaperLocked(false, FLAG_SET_SYSTEM, UserHandle.USER_SYSTEM, null);
+        // If we think we're going to be using the system image wallpaper imagery, make
+        // sure we have something to render
+        if (mImageWallpaper.equals(wallpaper.nextWallpaperComponent)) {
+            // No crop file? Make sure we've finished the processing sequence if necessary
+            if (!wallpaper.cropExists()) {
+                if (DEBUG) {
+                    Slog.i(TAG, "No crop; regenerating from source");
+                }
+                generateCrop(wallpaper);
+            }
+            // Still nothing?  Fall back to default.
+            if (!wallpaper.cropExists()) {
+                if (DEBUG) {
+                    Slog.i(TAG, "Unable to regenerate crop; resetting");
+                }
+                clearWallpaperLocked(false, FLAG_SET_SYSTEM, UserHandle.USER_SYSTEM, null);
+            }
+        } else {
+            if (DEBUG) {
+                Slog.i(TAG, "Nondefault wallpaper component; gracefully ignoring");
+            }
         }
         switchWallpaper(wallpaper, null);
         wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index 55b3c7b..3a5dec9 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -171,17 +171,21 @@
         transformation.setAlpha(mAppToken.isVisible() ? 1 : 0);
     }
 
+    void setNullAnimation() {
+        animation = null;
+        usingTransferredAnimation = false;
+    }
+
     public void clearAnimation() {
         if (animation != null) {
-            animation = null;
             animating = true;
         }
         clearThumbnail();
+        setNullAnimation();
         if (mAppToken.deferClearAllDrawn) {
             mAppToken.allDrawn = false;
             mAppToken.deferClearAllDrawn = false;
         }
-        usingTransferredAnimation = false;
     }
 
     public boolean isAnimating() {
@@ -202,9 +206,9 @@
 
         if (animation != null) {
             toAppAnimator.animation = animation;
-            animation = null;
             toAppAnimator.animating = animating;
             toAppAnimator.animLayerAdjustment = animLayerAdjustment;
+            setNullAnimation();
             animLayerAdjustment = 0;
             toAppAnimator.updateLayers();
             updateLayers();
@@ -311,7 +315,7 @@
                 if (mProlongAnimation == PROLONG_ANIMATION_AT_END) {
                     hasMoreFrames = true;
                 } else {
-                    animation = null;
+                    setNullAnimation();
                     clearThumbnail();
                     if (DEBUG_ANIM) Slog.v(TAG, "Finished animation in " + mAppToken + " @ "
                             + currentTime);
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 9795c93..4ec297e 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -322,23 +322,6 @@
         }
     }
 
-    void setWindowsExiting(boolean exiting) {
-        for (int i = allAppWindows.size() - 1; i >= 0; i--) {
-            WindowState win = allAppWindows.get(i);
-            // If the app already requested to remove its window, we don't modify
-            // its exiting state. Otherwise the stale window won't get removed on
-            // exit and could cause focus to be given to the wrong window.
-            if (!(win.mRemoveOnExit && win.mAnimatingExit)) {
-                win.mAnimatingExit = exiting;
-            }
-            // If we're no longer exiting, remove the window from destroying list
-            if (!win.mAnimatingExit && win.mDestroying) {
-                win.mDestroying = false;
-                service.mDestroySurface.remove(win);
-            }
-        }
-    }
-
     // Here we destroy surfaces which have been marked as eligible by the animator, taking care
     // to ensure the client has finished with them. If the client could still be using them
     // we will skip destruction and try again when the client has stopped.
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index e42658e..b702180 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -24,6 +24,7 @@
 
 import android.app.ActivityManagerNative;
 import android.graphics.Rect;
+import android.os.Debug;
 import android.os.RemoteException;
 import android.util.Log;
 import android.util.Slog;
@@ -36,6 +37,7 @@
 import com.android.server.input.InputManagerService;
 import com.android.server.input.InputWindowHandle;
 
+import java.io.PrintWriter;
 import java.util.Arrays;
 
 final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
@@ -47,6 +49,9 @@
     // When true, prevents input dispatch from proceeding until set to false again.
     private boolean mInputDispatchFrozen;
 
+    // The reason the input is currently frozen or null if the input isn't frozen.
+    private String mInputFreezeReason = null;
+
     // When true, input dispatch proceeds normally.  Otherwise all events are dropped.
     // Initially false, so that input does not get dispatched until boot is finished at
     // which point the ActivityManager will enable dispatching.
@@ -474,12 +479,16 @@
     }
 
     public void freezeInputDispatchingLw() {
-        if (! mInputDispatchFrozen) {
+        if (!mInputDispatchFrozen) {
             if (DEBUG_INPUT) {
                 Slog.v(TAG_WM, "Freezing input dispatching");
             }
 
             mInputDispatchFrozen = true;
+
+            if (DEBUG_INPUT || true) {
+                mInputFreezeReason = Debug.getCallers(6);
+            }
             updateInputDispatchModeLw();
         }
     }
@@ -491,6 +500,7 @@
             }
 
             mInputDispatchFrozen = false;
+            mInputFreezeReason = null;
             updateInputDispatchModeLw();
         }
     }
@@ -509,4 +519,10 @@
     private void updateInputDispatchModeLw() {
         mService.mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
     }
+
+    void dump(PrintWriter pw, String prefix) {
+        if (mInputFreezeReason != null) {
+            pw.println(prefix + "mInputFreezeReason=" + mInputFreezeReason);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 2e424d0..e44b0f3 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -508,10 +508,11 @@
 
             replacing = replacing || w.mWillReplaceWindow;
 
-            // If the app is executing an animation because the keyguard is going away,
-            // keep the wallpaper during the animation so it doesn't flicker out.
+            // If the app is executing an animation because the keyguard is going away (and the
+            // keyguard was showing the wallpaper) keep the wallpaper during the animation so it
+            // doesn't flicker out.
             final boolean hasWallpaper = (w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0
-                    || (w.mAppToken != null && w.mWinAnimator.mKeyguardGoingAwayAnimation);
+                    || (w.mAppToken != null && w.mWinAnimator.mKeyguardGoingAwayWithWallpaper);
             if (hasWallpaper && w.isOnScreen() && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
                 if (DEBUG_WALLPAPER) Slog.v(TAG, "Found wallpaper target: #" + i + "=" + w);
                 result.setWallpaperTarget(w, i);
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 4698e4e..f243761 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -22,6 +22,9 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
+import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
+import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEYGUARD;
@@ -98,8 +101,7 @@
     boolean mInitialized = false;
 
     boolean mKeyguardGoingAway;
-    boolean mKeyguardGoingAwayToNotificationShade;
-    boolean mKeyguardGoingAwayDisableWindowAnimations;
+    int mKeyguardGoingAwayFlags;
 
     /** Use one animation for all entering activities after keyguard is dismissed. */
     Animation mPostKeyguardExitAnimation;
@@ -243,6 +245,13 @@
 
         final WindowList windows = mService.getWindowListLocked(displayId);
 
+        final boolean keyguardGoingAwayToShade =
+                (mKeyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_TO_SHADE) != 0;
+        final boolean keyguardGoingAwayNoAnimation =
+                (mKeyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS) != 0;
+        final boolean keyguardGoingAwayWithWallpaper =
+                (mKeyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER) != 0;
+
         if (mKeyguardGoingAway) {
             for (int i = windows.size() - 1; i >= 0; i--) {
                 WindowState win = windows.get(i);
@@ -261,6 +270,8 @@
                         winAnimator.mAnimationIsEntrance = false;
                         winAnimator.mAnimationStartTime = -1;
                         winAnimator.mKeyguardGoingAwayAnimation = true;
+                        winAnimator.mKeyguardGoingAwayWithWallpaper
+                                = keyguardGoingAwayWithWallpaper;
                     }
                 } else {
                     if (DEBUG_KEYGUARD) Slog.d(TAG,
@@ -392,10 +403,13 @@
                             if (DEBUG_KEYGUARD) Slog.v(TAG,
                                     "Applying existing Keyguard exit animation to new window: win="
                                             + win);
-                            Animation a = mPolicy.createForceHideEnterAnimation(
-                                    false, mKeyguardGoingAwayToNotificationShade);
+
+                            Animation a = mPolicy.createForceHideEnterAnimation(false,
+                                    keyguardGoingAwayToShade);
                             winAnimator.setAnimation(a, mPostKeyguardExitAnimation.getStartTime());
                             winAnimator.mKeyguardGoingAwayAnimation = true;
+                            winAnimator.mKeyguardGoingAwayWithWallpaper
+                                    = keyguardGoingAwayWithWallpaper;
                         }
                         final WindowState currentFocus = mService.mCurrentFocus;
                         if (currentFocus == null || currentFocus.mLayer < win.mLayer) {
@@ -463,18 +477,20 @@
         // being force-hidden, apply the appropriate animation to them if animations are not
         // disabled.
         if (unForceHiding != null) {
-            if (!mKeyguardGoingAwayDisableWindowAnimations) {
+            if (!keyguardGoingAwayNoAnimation) {
                 boolean first = true;
                 for (int i=unForceHiding.size()-1; i>=0; i--) {
                     final WindowStateAnimator winAnimator = unForceHiding.get(i);
                     Animation a = mPolicy.createForceHideEnterAnimation(
                             wallpaperInUnForceHiding && !startingInUnForceHiding,
-                            mKeyguardGoingAwayToNotificationShade);
+                            keyguardGoingAwayToShade);
                     if (a != null) {
                         if (DEBUG_KEYGUARD) Slog.v(TAG,
                                 "Starting keyguard exit animation on window " + winAnimator.mWin);
                         winAnimator.setAnimation(a);
                         winAnimator.mKeyguardGoingAwayAnimation = true;
+                        winAnimator.mKeyguardGoingAwayWithWallpaper
+                                = keyguardGoingAwayWithWallpaper;
                         if (first) {
                             mPostKeyguardExitAnimation = a;
                             mPostKeyguardExitAnimation.setStartTime(mCurrentTime);
@@ -489,11 +505,10 @@
 
 
             // Wallpaper is going away in un-force-hide motion, animate it as well.
-            if (!wallpaperInUnForceHiding && wallpaper != null
-                    && !mKeyguardGoingAwayDisableWindowAnimations) {
+            if (!wallpaperInUnForceHiding && wallpaper != null && !keyguardGoingAwayNoAnimation) {
                 if (DEBUG_KEYGUARD) Slog.d(TAG, "updateWindowsLocked: wallpaper animating away");
                 Animation a = mPolicy.createForceHideWallpaperExitAnimation(
-                        mKeyguardGoingAwayToNotificationShade);
+                        keyguardGoingAwayToShade);
                 if (a != null) {
                     wallpaper.mWinAnimator.setAnimation(a);
                 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 304449d..607a3e9 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2626,7 +2626,8 @@
                 }
 
                 // Odd choice but less odd than embedding in copyFrom()
-                if ((attrs.flags & WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY) != 0) {
+                if ((attrs.privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY)
+                        != 0) {
                     attrs.x = win.mAttrs.x;
                     attrs.y = win.mAttrs.y;
                     attrs.width = win.mAttrs.width;
@@ -2825,10 +2826,12 @@
         if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) {
             focusMayChange = isDefaultDisplay;
             win.mAnimatingExit = true;
+            win.mWinAnimator.mAnimating = true;
         } else if (win.mWinAnimator.isAnimating()) {
             // Currently in a hide animation... turn this into
             // an exit.
             win.mAnimatingExit = true;
+            win.mWinAnimator.mAnimating = true;
         } else if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
             // If the wallpaper is currently behind this
             // window, we need to change both of them inside
@@ -4085,7 +4088,7 @@
 
             if (transit != AppTransition.TRANSIT_UNSET) {
                 if (wtoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
-                    wtoken.mAppAnimator.animation = null;
+                    wtoken.mAppAnimator.setNullAnimation();
                 }
                 if (applyAnimationLocked(wtoken, lp, transit, visible, isVoiceInteraction)) {
                     delayed = runningAppAnimation = true;
@@ -4195,7 +4198,7 @@
     void updateTokenInPlaceLocked(AppWindowToken wtoken, int transit) {
         if (transit != AppTransition.TRANSIT_UNSET) {
             if (wtoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
-                wtoken.mAppAnimator.animation = null;
+                wtoken.mAppAnimator.setNullAnimation();
             }
             applyAnimationLocked(wtoken, null, transit, false, false);
         }
@@ -4252,17 +4255,12 @@
                 wtoken.appDied = false;
                 wtoken.removeAllWindows();
             } else if (visible) {
-                if (DEBUG_ADD_REMOVE) Slog.v(
-                        TAG_WM, "No longer Stopped: " + wtoken);
-                wtoken.mAppStopped = false;
-                wtoken.setWindowsExiting(false);
                 mOpeningApps.add(wtoken);
                 wtoken.startingMoved = false;
 
-                // If the token is currently hidden (should be the
-                // common case), then we need to set up to wait for
-                // its windows to be ready.
-                if (wtoken.hidden) {
+                // If the token is currently hidden (should be the common case), or has been
+                // stopped, then we need to set up to wait for its windows to be ready.
+                if (wtoken.hidden || wtoken.mAppStopped) {
                     wtoken.allDrawn = false;
                     wtoken.deferClearAllDrawn = false;
                     wtoken.waitingToShow = true;
@@ -4278,6 +4276,9 @@
                         wtoken.sendAppVisibilityToClients();
                     }
                 }
+                if (DEBUG_ADD_REMOVE) Slog.v(
+                        TAG_WM, "No longer Stopped: " + wtoken);
+                wtoken.mAppStopped = false;
             }
 
             // If we are preparing an app transition, then delay changing
@@ -4287,6 +4288,11 @@
                 // animation is going on (in this case an application transition). If the animation
                 // was transferred from another application/animator, no dummy animator should be
                 // created since an animation is already in progress.
+                if (wtoken.mAppAnimator.usingTransferredAnimation
+                        && wtoken.mAppAnimator.animation == null) {
+                    Slog.wtf(TAG_WM, "Will NOT set dummy animation on: " + wtoken
+                            + ", using null transfered animation!");
+                }
                 if (!wtoken.mAppAnimator.usingTransferredAnimation &&
                         (!wtoken.startingDisplayed || mSkipAppTransitionAnimation)) {
                     if (DEBUG_APP_TRANSITIONS) Slog.v(
@@ -4297,7 +4303,6 @@
                 if (visible) {
                     wtoken.mEnteringAnimation = true;
                 } else {
-                    wtoken.setWindowsExiting(true);
                     mClosingApps.add(wtoken);
                     wtoken.mEnteringAnimation = false;
                 }
@@ -5173,18 +5178,16 @@
     }
 
     @Override
-    public void keyguardGoingAway(boolean disableWindowAnimations,
-            boolean keyguardGoingToNotificationShade) {
+    public void keyguardGoingAway(int flags) {
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires DISABLE_KEYGUARD permission");
         }
-        if (DEBUG_KEYGUARD) Slog.d(TAG_WM, "keyguardGoingAway: disableWinAnim="
-                + disableWindowAnimations + " kgToNotifShade=" + keyguardGoingToNotificationShade);
+        if (DEBUG_KEYGUARD) Slog.d(TAG_WM,
+                "keyguardGoingAway: flags=0x" + Integer.toHexString(flags));
         synchronized (mWindowMap) {
             mAnimator.mKeyguardGoingAway = true;
-            mAnimator.mKeyguardGoingAwayToNotificationShade = keyguardGoingToNotificationShade;
-            mAnimator.mKeyguardGoingAwayDisableWindowAnimations = disableWindowAnimations;
+            mAnimator.mKeyguardGoingAwayFlags = flags;
             mWindowPlacerLocked.requestTraversal();
         }
     }
@@ -9907,6 +9910,9 @@
                     pw.print(mLastFinishedFreezeSource);
                 }
                 pw.println();
+
+        mInputMonitor.dump(pw, "  ");
+
         if (dumpAll) {
             pw.print("  mSystemDecorLayer="); pw.print(mSystemDecorLayer);
                     pw.print(" mScreenRect="); pw.println(mScreenRect.toShortString());
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 910788e..cd771ba 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -642,7 +642,7 @@
         mHaveFrame = true;
 
         final Task task = getTask();
-        final boolean fullscreenTask = task == null || task.isFullscreen();
+        final boolean fullscreenTask = !inMultiWindowMode();
         final boolean windowsAreFloating = task != null && task.isFloating();
 
         if (fullscreenTask || (isChildWindow()
@@ -670,8 +670,8 @@
             }
 
             if (windowsAreFloating) {
-                // In floating modes (e.g. freeform, pinned) we have only to set the rectangle 
-                // if it wasn't set already. No need to intersect it with the (visible) 
+                // In floating modes (e.g. freeform, pinned) we have only to set the rectangle
+                // if it wasn't set already. No need to intersect it with the (visible)
                 // "content frame" since it is allowed to be outside the visible desktop.
                 if (mContainingFrame.isEmpty()) {
                     mContainingFrame.set(cf);
@@ -2215,6 +2215,12 @@
         return task != null && task.inFreeformWorkspace();
     }
 
+    @Override
+    public boolean inMultiWindowMode() {
+        final Task task = getTask();
+        return task != null && !task.isFullscreen();
+    }
+
     boolean isDragResizeChanged() {
         return mDragResizing != computeDragResizing();
     }
@@ -2506,9 +2512,8 @@
         final int pw = mContainingFrame.width();
         final int ph = mContainingFrame.height();
         final Task task = getTask();
-        final boolean nonFullscreenTask = task != null && !task.isFullscreen();
-        final boolean fitToDisplay = task != null &&
-            !task.isFloating();
+        final boolean nonFullscreenTask = inMultiWindowMode();
+        final boolean fitToDisplay = task != null && !task.isFloating();
         float x, y;
         int w,h;
 
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index bf8a62e..6ce1a64 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -160,6 +160,7 @@
     boolean mEnteringAnimation;
 
     boolean mKeyguardGoingAwayAnimation;
+    boolean mKeyguardGoingAwayWithWallpaper;
 
     /** The pixel format of the underlying SurfaceControl */
     int mSurfaceFormat;
@@ -250,6 +251,7 @@
             mAnimation.cancel();
             mAnimation = null;
             mKeyguardGoingAwayAnimation = false;
+            mKeyguardGoingAwayWithWallpaper = false;
         }
     }
 
@@ -381,6 +383,7 @@
 
         mAnimating = false;
         mKeyguardGoingAwayAnimation = false;
+        mKeyguardGoingAwayWithWallpaper = false;
         mLocalAnimating = false;
         if (mAnimation != null) {
             mAnimation.cancel();
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 8ada2f1..5ad771f 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -1158,7 +1158,7 @@
 
             if (!appAnimator.usingTransferredAnimation) {
                 appAnimator.clearThumbnail();
-                appAnimator.animation = null;
+                appAnimator.setNullAnimation();
             }
             wtoken.inPendingTransaction = false;
 
@@ -1231,7 +1231,7 @@
             final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
             appAnimator.clearThumbnail();
-            appAnimator.animation = null;
+            appAnimator.setNullAnimation();
             wtoken.inPendingTransaction = false;
             mService.setTokenVisibilityLocked(wtoken, animLp, false, transit, false,
                     voiceInteraction);
@@ -1494,7 +1494,7 @@
                 if (DEBUG_APP_TRANSITIONS)
                     Slog.v(TAG, "Now animating app in place " + wtoken);
                 appAnimator.clearThumbnail();
-                appAnimator.animation = null;
+                appAnimator.setNullAnimation();
                 mService.updateTokenInPlaceLocked(wtoken, transit);
                 wtoken.updateReportedVisibilityLocked();
 
diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp
index 6c640ba..c4316f6 100644
--- a/services/core/jni/com_android_server_tv_TvInputHal.cpp
+++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp
@@ -400,7 +400,7 @@
                 connection.mThread->shutdown();
             }
             connection.mThread = new BufferProducerThread(mDevice, deviceId, &stream);
-            connection.mThread->run();
+            connection.mThread->run("BufferProducerThread");
         }
     }
     connection.mSurface = surface;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index ea1a569..16e73fc 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -33,6 +33,7 @@
 import android.accounts.AccountManager;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -83,6 +84,7 @@
 import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.Build;
+import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.FileUtils;
@@ -113,6 +115,7 @@
 import android.security.KeyChain;
 import android.security.KeyChain.KeyChainConnection;
 import android.service.persistentdata.PersistentDataBlockManager;
+import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -304,6 +307,7 @@
     final IPackageManager mIPackageManager;
     final UserManager mUserManager;
     final UserManagerInternal mUserManagerInternal;
+    final TelephonyManager mTelephonyManager;
     private final LockPatternUtils mLockPatternUtils;
 
     /**
@@ -1352,6 +1356,10 @@
             return LocalServices.getService(PowerManagerInternal.class);
         }
 
+        TelephonyManager getTelephonyManager() {
+            return TelephonyManager.from(mContext);
+        }
+
         IWindowManager getIWindowManager() {
             return IWindowManager.Stub
                     .asInterface(ServiceManager.getService(Context.WINDOW_SERVICE));
@@ -1378,6 +1386,22 @@
             return new LockPatternUtils(mContext);
         }
 
+        boolean storageManagerIsFileBasedEncryptionEnabled() {
+            return StorageManager.isFileEncryptedNativeOnly();
+        }
+
+        boolean storageManagerIsNonDefaultBlockEncrypted() {
+            return StorageManager.isNonDefaultBlockEncrypted();
+        }
+
+        boolean storageManagerIsEncrypted() {
+            return StorageManager.isEncrypted();
+        }
+
+        boolean storageManagerIsEncryptable() {
+            return StorageManager.isEncryptable();
+        }
+
         Looper getMyLooper() {
             return Looper.myLooper();
         }
@@ -1524,6 +1548,7 @@
         mUserManager = Preconditions.checkNotNull(injector.getUserManager());
         mUserManagerInternal = Preconditions.checkNotNull(injector.getUserManagerInternal());
         mIPackageManager = Preconditions.checkNotNull(injector.getIPackageManager());
+        mTelephonyManager = Preconditions.checkNotNull(injector.getTelephonyManager());
 
         mLocalService = new LocalService();
         mLockPatternUtils = injector.newLockPatternUtils();
@@ -1646,12 +1671,14 @@
         } else {
             if (mOwners.hasDeviceOwner()) {
                 mInjector.systemPropertiesSet(PROPERTY_DEVICE_OWNER_PRESENT, "true");
+                Slog.i(LOG_TAG, "Set ro.device_owner property to true");
                 disableDeviceLoggingIfNotCompliant();
                 if (mInjector.securityLogGetLoggingEnabledProperty()) {
                     mSecurityLogMonitor.start();
                 }
             } else {
                 mInjector.systemPropertiesSet(PROPERTY_DEVICE_OWNER_PRESENT, "false");
+                Slog.i(LOG_TAG, "Set ro.device_owner property to false");
             }
         }
     }
@@ -2866,13 +2893,9 @@
     @Override
     public boolean isSeparateProfileChallengeAllowed(int userHandle) {
         ComponentName profileOwner = getProfileOwner(userHandle);
-        try {
-            // Profile challenge is supported on N or newer release.
-            return profileOwner != null &&
-                    getTargetSdk(profileOwner.getPackageName(), userHandle) > Build.VERSION_CODES.M;
-        } catch (RemoteException e) {
-            return false;
-        }
+        // Profile challenge is supported on N or newer release.
+        return profileOwner != null &&
+                getTargetSdk(profileOwner.getPackageName(), userHandle) > Build.VERSION_CODES.M;
     }
 
     @Override
@@ -4236,15 +4259,12 @@
         int userHandle = UserHandle.getCallingUserId();
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
-            try {
-                if (getTargetSdk(who.getPackageName(), userHandle) >= Build.VERSION_CODES.N) {
-                    if (installerPackage != null &&
-                            !isPackageInstalledForUser(installerPackage, userHandle)) {
-                        throw new IllegalArgumentException("Package " + installerPackage
-                                + " is not installed on the current user");
-                    }
+            if (getTargetSdk(who.getPackageName(), userHandle) >= Build.VERSION_CODES.N) {
+                if (installerPackage != null &&
+                        !isPackageInstalledForUser(installerPackage, userHandle)) {
+                    throw new IllegalArgumentException("Package " + installerPackage
+                            + " is not installed on the current user");
                 }
-            } catch (RemoteException e) {
             }
             DevicePolicyData policy = getUserData(userHandle);
             policy.mDelegatedCertInstallerPackage = installerPackage;
@@ -4835,12 +4855,23 @@
      * Get the current encryption status of the device.
      */
     @Override
-    public int getStorageEncryptionStatus(int userHandle) {
+    public int getStorageEncryptionStatus(@Nullable String callerPackage, int userHandle) {
         if (!mHasFeature) {
             // Ok to return current status.
         }
         enforceFullCrossUsersPermission(userHandle);
-        return getEncryptionStatus();
+
+        // It's not critical here, but let's make sure the package name is correct, in case
+        // we start using it for different purposes.
+        ensureCallerPackage(callerPackage);
+
+        final int rawStatus = getEncryptionStatus();
+        if ((rawStatus == DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER)
+                && (callerPackage != null)
+                && (getTargetSdk(callerPackage, userHandle) <= VERSION_CODES.M)) {
+            return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE;
+        }
+        return rawStatus;
     }
 
     /**
@@ -4858,15 +4889,18 @@
      * Hook to low-levels:  Reporting the current status of encryption.
      * @return A value such as {@link DevicePolicyManager#ENCRYPTION_STATUS_UNSUPPORTED},
      * {@link DevicePolicyManager#ENCRYPTION_STATUS_INACTIVE},
-     * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY}, or
+     * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY},
+     * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE_PER_USER}, or
      * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE}.
      */
     private int getEncryptionStatus() {
-        if (StorageManager.isEncrypted()) {
-            return StorageManager.isNonDefaultBlockEncrypted() ?
-                      DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE
-                    : DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY;
-        } else if (StorageManager.isEncryptable()) {
+        if (mInjector.storageManagerIsFileBasedEncryptionEnabled()) {
+            return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER;
+        } else if (mInjector.storageManagerIsNonDefaultBlockEncrypted()) {
+            return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE;
+        } else if (mInjector.storageManagerIsEncrypted()) {
+            return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY;
+        } else if (mInjector.storageManagerIsEncryptable()) {
             return DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE;
         } else {
             return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
@@ -4879,7 +4913,6 @@
     private void setEncryptionRequested(boolean encrypt) {
     }
 
-
     /**
      * Set whether the screen capture is disabled for the user managed by the specified admin.
      */
@@ -6037,6 +6070,23 @@
         }
     }
 
+    private void ensureCallerPackage(@Nullable String packageName) {
+        if (packageName == null) {
+            Preconditions.checkState(isCallerWithSystemUid(),
+                    "Only caller can omit package name");
+        } else {
+            final int callingUid = mInjector.binderGetCallingUid();
+            final int userId = mInjector.userHandleGetCallingUserId();
+            try {
+                final ApplicationInfo ai = mIPackageManager.getApplicationInfo(
+                        packageName, 0, userId);
+                Preconditions.checkState(ai.uid == callingUid, "Unmatching package name");
+            } catch (RemoteException e) {
+                // Shouldn't happen
+            }
+        }
+    }
+
     private boolean isCallerWithSystemUid() {
         return UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID);
     }
@@ -6122,6 +6172,27 @@
                 pw.println(" ");
                 pw.print("    mPasswordOwner="); pw.println(policy.mPasswordOwner);
             }
+            pw.println();
+            pw.println("Encryption Status: " + getEncryptionStatusName(getEncryptionStatus()));
+        }
+    }
+
+    private String getEncryptionStatusName(int encryptionStatus) {
+        switch (encryptionStatus) {
+            case DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE:
+                return "inactive";
+            case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY:
+                return "block default key";
+            case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE:
+                return "block";
+            case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER:
+                return "per-user";
+            case DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED:
+                return "unsupported";
+            case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVATING:
+                return "activating";
+            default:
+                return "unknown";
         }
     }
 
@@ -7831,6 +7902,29 @@
             }
             return false;
         }
+
+        @Override
+        public Intent createPackageSuspendedDialogIntent(String packageName, int userId) {
+            Intent intent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS);
+            intent.putExtra(Intent.EXTRA_USER_ID, userId);
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            synchronized (DevicePolicyManagerService.this) {
+                ComponentName profileOwner = mOwners.getProfileOwnerComponent(userId);
+                if (profileOwner != null) {
+                    intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, profileOwner);
+                    return intent;
+                }
+
+                if (mOwners.getDeviceOwnerUserId() == userId) {
+                    ComponentName deviceOwner = mOwners.getDeviceOwnerComponent();
+                    if (deviceOwner != null) {
+                        intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, deviceOwner);
+                        return intent;
+                    }
+                }
+            }
+            return null;
+        }
     }
 
     /**
@@ -8207,11 +8301,16 @@
      * Returns the target sdk version number that the given packageName was built for
      * in the given user.
      */
-    private int getTargetSdk(String packageName, int userId) throws RemoteException {
-        final ApplicationInfo ai = mIPackageManager
-                .getApplicationInfo(packageName, 0, userId);
-        final int targetSdkVersion = ai == null ? 0 : ai.targetSdkVersion;
-        return targetSdkVersion;
+    private int getTargetSdk(String packageName, int userId) {
+        final ApplicationInfo ai;
+        try {
+            ai = mIPackageManager.getApplicationInfo(packageName, 0, userId);
+            final int targetSdkVersion = ai == null ? 0 : ai.targetSdkVersion;
+            return targetSdkVersion;
+        } catch (RemoteException e) {
+            // Shouldn't happen
+            return 0;
+        }
     }
 
     @Override
@@ -8242,6 +8341,10 @@
         }
         long ident = mInjector.binderClearCallingIdentity();
         try {
+            // Make sure there are no ongoing calls on the device.
+            if (mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE) {
+                throw new IllegalStateException("Cannot be called with ongoing call on the device");
+            }
             mInjector.powerManagerReboot(PowerManager.REBOOT_REQUESTED_BY_DEVICE_OWNER);
         } finally {
             mInjector.binderRestoreCallingIdentity(ident);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e7daaa1..fc0ac0b 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -518,6 +518,16 @@
         boolean disableNetwork = SystemProperties.getBoolean("config.disable_network", false);
         boolean disableNetworkTime = SystemProperties.getBoolean("config.disable_networktime", false);
         boolean disableRtt = SystemProperties.getBoolean("config.disable_rtt", false);
+        boolean disableMediaProjection = SystemProperties.getBoolean("config.disable_mediaproj",
+                false);
+        boolean disableSerial = SystemProperties.getBoolean("config.disable_serial", false);
+        boolean disableSearchManager = SystemProperties.getBoolean("config.disable_searchmanager",
+                false);
+        boolean disableTrustManager = SystemProperties.getBoolean("config.disable_trustmanager",
+                false);
+        boolean disableTextServices = SystemProperties.getBoolean("config.disable_textservices", false);
+        boolean disableSamplingProfiler = SystemProperties.getBoolean("config.disable_samplingprof",
+                false);
         boolean isEmulator = SystemProperties.get("ro.kernel.qemu").equals("1");
 
         try {
@@ -761,7 +771,7 @@
                 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
-            if (!disableNonCoreServices) {
+            if (!disableNonCoreServices && !disableTextServices) {
                 mSystemServiceManager.startService(TextServicesManagerService.Lifecycle.class);
             }
 
@@ -912,7 +922,7 @@
                 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
-            if (!disableNonCoreServices) {
+            if (!disableNonCoreServices && !disableSearchManager) {
                 traceBeginAndSlog("StartSearchManagerService");
                 try {
                     mSystemServiceManager.startService(SEARCH_MANAGER_SERVICE_CLASS);
@@ -974,15 +984,17 @@
                     Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
                 }
 
-                traceBeginAndSlog("StartSerialService");
-                try {
-                    // Serial port support
-                    serial = new SerialService(context);
-                    ServiceManager.addService(Context.SERIAL_SERVICE, serial);
-                } catch (Throwable e) {
-                    Slog.e(TAG, "Failure starting SerialService", e);
+                if (!disableSerial) {
+                    traceBeginAndSlog("StartSerialService");
+                    try {
+                        // Serial port support
+                        serial = new SerialService(context);
+                        ServiceManager.addService(Context.SERIAL_SERVICE, serial);
+                    } catch (Throwable e) {
+                        Slog.e(TAG, "Failure starting SerialService", e);
+                    }
+                    Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
                 }
-                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
                 Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER,
                         "StartHardwarePropertiesManagerService");
@@ -1030,18 +1042,20 @@
             }
             Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
-            traceBeginAndSlog("StartSamplingProfilerService");
-            try {
-                // need to add this service even if SamplingProfilerIntegration.isEnabled()
-                // is false, because it is this service that detects system property change and
-                // turns on SamplingProfilerIntegration. Plus, when sampling profiler doesn't work,
-                // there is little overhead for running this service.
-                ServiceManager.addService("samplingprofiler",
-                            new SamplingProfilerService(context));
-            } catch (Throwable e) {
-                reportWtf("starting SamplingProfiler Service", e);
+            if (!disableSamplingProfiler) {
+                traceBeginAndSlog("StartSamplingProfilerService");
+                try {
+                    // need to add this service even if SamplingProfilerIntegration.isEnabled()
+                    // is false, because it is this service that detects system property change and
+                    // turns on SamplingProfilerIntegration. Plus, when sampling profiler doesn't work,
+                    // there is little overhead for running this service.
+                    ServiceManager.addService("samplingprofiler",
+                                new SamplingProfilerService(context));
+                } catch (Throwable e) {
+                    reportWtf("starting SamplingProfiler Service", e);
+                }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
-            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
             if (!disableNetwork && !disableNetworkTime) {
                 traceBeginAndSlog("StartNetworkTimeUpdateService");
@@ -1122,7 +1136,9 @@
                 }
                 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
-                mSystemServiceManager.startService(TrustManagerService.class);
+                if (!disableTrustManager) {
+                    mSystemServiceManager.startService(TrustManagerService.class);
+                }
 
                 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
                     mSystemServiceManager.startService(FingerprintService.class);
@@ -1142,7 +1158,7 @@
             mSystemServiceManager.startService(LauncherAppsService.class);
         }
 
-        if (!disableNonCoreServices) {
+        if (!disableNonCoreServices && !disableMediaProjection) {
             mSystemServiceManager.startService(MediaProjectionManagerService.class);
         }
 
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
index db2a9ad..35777ce 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -28,6 +28,8 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
+import android.os.storage.StorageManager;
+import android.telephony.TelephonyManager;
 import android.view.IWindowManager;
 
 import java.io.File;
@@ -163,6 +165,26 @@
         }
 
         @Override
+        boolean storageManagerIsFileBasedEncryptionEnabled() {
+            return context.storageManager.isFileBasedEncryptionEnabled();
+        }
+
+        @Override
+        boolean storageManagerIsNonDefaultBlockEncrypted() {
+            return context.storageManager.isNonDefaultBlockEncrypted();
+        }
+
+        @Override
+        boolean storageManagerIsEncrypted() {
+            return context.storageManager.isEncrypted();
+        }
+
+        @Override
+        boolean storageManagerIsEncryptable() {
+            return context.storageManager.isEncryptable();
+        }
+
+        @Override
         String getDevicePolicyFilePathForSystemUser() {
             return context.systemUserDataDir.getAbsolutePath() + "/";
         }
@@ -301,5 +323,10 @@
         boolean securityLogIsLoggingEnabled() {
             return context.settings.securityLogIsLoggingEnabled();
         }
+
+        @Override
+        TelephonyManager getTelephonyManager() {
+            return context.telephonyManager;
+        }
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index e897e3d..6c2bdda 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -33,6 +33,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.telephony.TelephonyManager;
 import android.test.MoreAsserts;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.ArraySet;
@@ -1491,7 +1492,7 @@
         assertEquals("11:22:33:44:55:66", dpm.getWifiMacAddress(admin1));
     }
 
-    public void testRebootCanOnlyBeCalledByDeviceOwner() throws Exception {
+    public void testReboot() throws Exception {
         mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
 
@@ -1524,6 +1525,29 @@
         dpm.clearProfileOwner(admin1);
         assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM));
 
+        // admin1 is DO.
+        // Set current call state of device to ringing.
+        when(mContext.telephonyManager.getCallState())
+                .thenReturn(TelephonyManager.CALL_STATE_RINGING);
+        try {
+            dpm.reboot(admin1);
+            fail("DPM.reboot() called when receiveing a call, should thrown IllegalStateException");
+        } catch (IllegalStateException expected) {
+            MoreAsserts.assertContainsRegex("ongoing call on the device", expected.getMessage());
+        }
+
+        // Set current call state of device to dialing/active.
+        when(mContext.telephonyManager.getCallState())
+                .thenReturn(TelephonyManager.CALL_STATE_OFFHOOK);
+        try {
+            dpm.reboot(admin1);
+            fail("DPM.reboot() called when dialing, should thrown IllegalStateException");
+        } catch (IllegalStateException expected) {
+            MoreAsserts.assertContainsRegex("ongoing call on the device", expected.getMessage());
+        }
+
+        // Set current call state of device to idle.
+        when(mContext.telephonyManager.getCallState()).thenReturn(TelephonyManager.CALL_STATE_IDLE);
         dpm.reboot(admin1);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
index ef8e420..8e2ef70 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
@@ -39,6 +39,8 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
+import android.os.storage.StorageManager;
+import android.telephony.TelephonyManager;
 import android.test.mock.MockContentResolver;
 import android.test.mock.MockContext;
 import android.view.IWindowManager;
@@ -211,6 +213,24 @@
         }
     }
 
+    public static class StorageManagerForMock {
+        public boolean isFileBasedEncryptionEnabled() {
+            return false;
+        }
+
+        public boolean isNonDefaultBlockEncrypted() {
+            return false;
+        }
+
+        public boolean isEncrypted() {
+            return false;
+        }
+
+        public boolean isEncryptable() {
+            return false;
+        }
+    }
+
     public final Context realTestContext;
 
     /**
@@ -239,9 +259,11 @@
     public final IBackupManager ibackupManager;
     public final IAudioService iaudioService;
     public final LockPatternUtils lockPatternUtils;
+    public final StorageManagerForMock storageManager;
     public final WifiManager wifiManager;
     public final SettingsForMock settings;
     public final MockContentResolver contentResolver;
+    public final TelephonyManager telephonyManager;
 
     /** Note this is a partial mock, not a real mock. */
     public final PackageManager packageManager;
@@ -272,8 +294,10 @@
         ibackupManager = mock(IBackupManager.class);
         iaudioService = mock(IAudioService.class);
         lockPatternUtils = mock(LockPatternUtils.class);
+        storageManager = mock(StorageManagerForMock.class);
         wifiManager = mock(WifiManager.class);
         settings = mock(SettingsForMock.class);
+        telephonyManager = mock(TelephonyManager.class);
 
         // Package manager is huge, so we use a partial mock instead.
         packageManager = spy(context.getPackageManager());
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java
index b9e9aa9..82c6b6d 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java
@@ -25,7 +25,7 @@
 import static org.mockito.Mockito.when;
 
 import static android.net.NetworkStats.SET_DEFAULT;
-import static android.net.NetworkStats.ROAMING_DEFAULT;
+import static android.net.NetworkStats.ROAMING_NO;
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
 import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
@@ -447,7 +447,7 @@
         // Baseline
         NetworkStats xtSnapshot = null;
         NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
                         BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -455,7 +455,7 @@
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START+ 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -487,7 +487,7 @@
         // Baseline
         NetworkStats xtSnapshot = null;
         NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
                         BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -495,7 +495,7 @@
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START+ 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -527,7 +527,7 @@
         // Baseline
         NetworkStats xtSnapshot = null;
         NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
                         BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -535,7 +535,7 @@
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START+ 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -567,7 +567,7 @@
         // Baseline
         NetworkStats xtSnapshot = null;
         NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
                         BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -575,7 +575,7 @@
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START+ 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -607,7 +607,7 @@
         // Baseline
         NetworkStats xtSnapshot = null;
         NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+                .addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, ROAMING_NO,
                         BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -615,7 +615,7 @@
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START+ 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+                .addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, ROAMING_NO,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java
index 4f6c7b9..74c1984 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java
@@ -23,8 +23,8 @@
 import static android.net.ConnectivityManager.TYPE_WIMAX;
 import static android.net.NetworkStats.IFACE_ALL;
 import static android.net.NetworkStats.ROAMING_ALL;
-import static android.net.NetworkStats.ROAMING_DEFAULT;
-import static android.net.NetworkStats.ROAMING_ROAMING;
+import static android.net.NetworkStats.ROAMING_NO;
+import static android.net.NetworkStats.ROAMING_YES;
 import static android.net.NetworkStats.SET_ALL;
 import static android.net.NetworkStats.SET_DEFAULT;
 import static android.net.NetworkStats.SET_FOREGROUND;
@@ -321,8 +321,8 @@
         // verify service recorded history
         assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
         assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
-        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, ROAMING_DEFAULT, 512L, 4L, 256L, 2L, 4);
-        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, ROAMING_DEFAULT, 512L, 4L, 256L, 2L,
+        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, ROAMING_NO, 512L, 4L, 256L, 2L, 4);
+        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, ROAMING_NO, 512L, 4L, 256L, 2L,
                 6);
         assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
         verifyAndReset();
@@ -357,8 +357,8 @@
         // after systemReady(), we should have historical stats loaded again
         assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
         assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
-        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, ROAMING_DEFAULT, 512L, 4L, 256L, 2L, 4);
-        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, ROAMING_DEFAULT, 512L, 4L, 256L, 2L,
+        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, ROAMING_NO, 512L, 4L, 256L, 2L, 4);
+        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, ROAMING_NO, 512L, 4L, 256L, 2L,
                 6);
         assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
         verifyAndReset();
@@ -711,11 +711,11 @@
         NetworkStats stats = mSession.getSummaryForAllUid(
                 sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
         assertEquals(3, stats.size());
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 50L, 5L,
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 50L, 5L,
                 50L, 5L, 1);
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 10L, 1L, 10L,
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_NO, 10L, 1L, 10L,
                 1L, 1);
-        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 2048L, 16L,
+        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, ROAMING_NO, 2048L, 16L,
                 1024L, 8L, 0);
 
         // now verify that recent history only contains one uid
@@ -723,7 +723,7 @@
         stats = mSession.getSummaryForAllUid(
                 sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true);
         assertEquals(1, stats.size());
-        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1024L, 8L,
+        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L,
                 512L, 4L, 0);
 
         verifyAndReset();
@@ -787,13 +787,13 @@
         final NetworkStats stats = mSession.getSummaryForAllUid(
                 sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
         assertEquals(4, stats.size());
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 128L, 2L,
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 2L,
                 128L, 2L, 1);
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 64L, 1L, 64L,
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 1L, 64L,
                 1L, 1);
-        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT, 32L, 2L,
+        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 32L, 2L,
                 32L, 2L, 1);
-        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, 0xFAAD, ROAMING_DEFAULT, 1L, 1L, 1L,
+        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, 0xFAAD, ROAMING_NO, 1L, 1L, 1L,
                 1L, 1);
 
         verifyAndReset();
@@ -818,13 +818,13 @@
         expectCurrentTime();
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
-        // Note that all traffic from NetworkManagementService is tagged as ROAMING_DEFAULT, because
+        // Note that all traffic from NetworkManagementService is tagged as ROAMING_NO, because
         // roaming isn't tracked at that layer. We layer it on top by inspecting the iface
         // properties.
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 128L, 2L,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 2L,
                         128L, 2L, 0L)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 64L, 1L, 64L,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 1L, 64L,
                         1L, 0L));
         expectNetworkStatsPoll();
 
@@ -838,9 +838,9 @@
         final NetworkStats stats = mSession.getSummaryForAllUid(
                 sTemplateImsi1, Long.MIN_VALUE, Long.MAX_VALUE, true);
         assertEquals(2, stats.size());
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 128L, 2L,
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_YES, 128L, 2L,
                 128L, 2L, 0);
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_ROAMING, 64L, 1L, 64L,
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_YES, 64L, 1L, 64L,
                 1L, 0);
 
         verifyAndReset();
@@ -1073,9 +1073,9 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 128L, 2L,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 2L,
                         128L, 2L, 0L)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 64L, 1L, 64L,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 1L, 64L,
                         1L, 0L));
         expectNetworkStatsPoll();
 
@@ -1089,9 +1089,9 @@
         NetworkStats stats = mSession.getSummaryForAllUid(
                 sTemplateImsi1, Long.MIN_VALUE, Long.MAX_VALUE, true);
         assertEquals(2, stats.size());
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 128L, 2L,
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_YES, 128L, 2L,
                 128L, 2L, 0);
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_ROAMING, 64L, 1L, 64L,
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_YES, 64L, 1L, 64L,
                 1L, 0);
 
         verifyAndReset();
@@ -1106,9 +1106,9 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
                         128000000L, 2L, 128000000L, 2L, 0L)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_NO,
                         64000000L, 1L, 64000000L, 1L, 0L));
         expectNetworkStatsPoll();
 
@@ -1122,9 +1122,9 @@
         stats = mSession.getSummaryForAllUid(
                 sTemplateImsi1, Long.MIN_VALUE, Long.MAX_VALUE, true);
         assertEquals(2, stats.size());
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING,
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_YES,
                 128000000L, 2L, 128000000L, 2L, 0);
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_ROAMING,
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_YES,
                 64000000L, 1L, 64000000L, 1L, 0);
 
         verifyAndReset();
@@ -1180,7 +1180,7 @@
 
         // verify summary API
         final NetworkStats stats = mSession.getSummaryForNetwork(template, start, end);
-        assertValues(stats, IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, rxBytes,
+        assertValues(stats, IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_NO, rxBytes,
                 rxPackets, txBytes, txPackets, operations);
     }
 
@@ -1312,11 +1312,11 @@
         }
 
         List<Integer> roamings = new ArrayList<>();
-        if (roaming == ROAMING_DEFAULT || roaming == ROAMING_ALL) {
-            roamings.add(ROAMING_DEFAULT);
+        if (roaming == ROAMING_NO || roaming == ROAMING_ALL) {
+            roamings.add(ROAMING_NO);
         }
-        if (roaming == ROAMING_ROAMING || roaming == ROAMING_ALL) {
-            roamings.add(ROAMING_ROAMING);
+        if (roaming == ROAMING_YES || roaming == ROAMING_ALL) {
+            roamings.add(ROAMING_YES);
         }
 
         for (int s : sets) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java
index f2c42db..6bcaf4d 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java
@@ -15,18 +15,27 @@
  */
 package com.android.server.pm;
 
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
 import android.app.Activity;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ILauncherApps;
 import android.content.pm.LauncherApps;
 import android.content.pm.LauncherApps.ShortcutQuery;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutManager;
 import android.content.pm.ShortcutServiceInternal;
@@ -38,10 +47,13 @@
 import android.os.BaseBundle;
 import android.os.Bundle;
 import android.os.FileUtils;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.test.AndroidTestCase;
+import android.test.InstrumentationTestCase;
 import android.test.mock.MockContext;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
@@ -57,6 +69,7 @@
 import libcore.io.IoUtils;
 
 import org.junit.Assert;
+import org.mockito.ArgumentCaptor;
 
 import java.io.BufferedReader;
 import java.io.ByteArrayOutputStream;
@@ -90,7 +103,7 @@
  *
  */
 @SmallTest
-public class ShortcutManagerTest extends AndroidTestCase {
+public class ShortcutManagerTest extends InstrumentationTestCase {
     private static final String TAG = "ShortcutManagerTest";
 
     /**
@@ -116,7 +129,14 @@
 
         @Override
         public Resources getResources() {
-            return ShortcutManagerTest.this.getContext().getResources();
+            return getTestContext().getResources();
+        }
+
+        @Override
+        public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
+                IntentFilter filter, String broadcastPermission, Handler scheduler) {
+            // ignore.
+            return null;
         }
     }
 
@@ -130,13 +150,24 @@
 
     /** Context used in the service side */
     private final class ServiceContext extends BaseContext {
+        long injectClearCallingIdentity() {
+            final int prevCallingUid = mInjectedCallingUid;
+            mInjectedCallingUid = Process.SYSTEM_UID;
+            return prevCallingUid;
+        }
+
+        void injectRestoreCallingIdentity(long token) {
+            mInjectedCallingUid = (int) token;
+        }
     }
 
     /** ShortcutService with injection override methods. */
     private final class ShortcutServiceTestable extends ShortcutService {
-        public ShortcutServiceTestable(Context context) {
-            super(context);
+        final ServiceContext mContext;
 
+        public ShortcutServiceTestable(ServiceContext context) {
+            super(context);
+            mContext = context;
         }
 
         @Override
@@ -152,6 +183,16 @@
         }
 
         @Override
+        long injectClearCallingIdentity() {
+            return mContext.injectClearCallingIdentity();
+        }
+
+        @Override
+        void injectRestoreCallingIdentity(long token) {
+            mContext.injectRestoreCallingIdentity(token);
+        }
+
+        @Override
         int injectDipToPixel(int dip) {
             return dip;
         }
@@ -191,6 +232,24 @@
         boolean injectIsLowRamDevice() {
             return mInjectdIsLowRamDevice;
         }
+
+        @Override
+        PackageManagerInternal injectPackageManagerInternal() {
+            return mMockPackageManagerInternal;
+        }
+
+        @Override
+        boolean hasShortcutHostPermission(@NonNull String callingPackage, int userId) {
+            // Sort of hack; do a simpler check.
+            return LAUNCHER_1.equals(callingPackage) || LAUNCHER_2.equals(callingPackage);
+        }
+
+        @Override
+        void postToHandler(Runnable r) {
+            final long token = mContext.injectClearCallingIdentity();
+            r.run();
+            mContext.injectRestoreCallingIdentity(token);
+        }
     }
 
     /** ShortcutManager with injection override methods. */
@@ -206,12 +265,20 @@
     }
 
     private class LauncherAppImplTestable extends LauncherAppsImpl {
-        public LauncherAppImplTestable(Context context) {
+        final ServiceContext mContext;
+
+        public LauncherAppImplTestable(ServiceContext context) {
             super(context);
+            mContext = context;
         }
 
         @Override
         public void ensureInUserProfiles(UserHandle userToCheck, String message) {
+            if (getCallingUserId() == userToCheck.getIdentifier()) {
+                return; // okay
+            }
+
+            assertEquals(Process.SYSTEM_UID, mInjectedCallingUid);
             // SKIP
         }
 
@@ -219,6 +286,20 @@
         public void verifyCallingPackage(String callingPackage) {
             // SKIP
         }
+
+        @Override
+        boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser, String debugMsg) {
+            // This requires CROSS_USER
+            assertEquals(Process.SYSTEM_UID, mInjectedCallingUid);
+            return user.getIdentifier() == listeningUser.getIdentifier();
+        }
+
+        @Override
+        void postToPackageMonitor(Runnable r) {
+            final long token = mContext.injectClearCallingIdentity();
+            r.run();
+            mContext.injectRestoreCallingIdentity(token);
+        }
     }
 
     private class LauncherAppsTestable extends LauncherApps {
@@ -258,6 +339,7 @@
     private Map<String, Integer> mInjectedPackageUidMap;
 
     private PackageManager mMockPackageManager;
+    private PackageManagerInternal mMockPackageManagerInternal;
     private UserManager mMockUserManager;
 
     private static final String CALLING_PACKAGE_1 = "com.android.test.1";
@@ -275,6 +357,7 @@
     private static final String LAUNCHER_2 = "com.android.launcher.2";
     private static final int LAUNCHER_UID_2 = 10012;
 
+    private static final int USER_0 = UserHandle.USER_SYSTEM;
     private static final int USER_10 = 10;
     private static final int USER_11 = 11;
 
@@ -298,6 +381,7 @@
         mClientContext = new ClientContext();
 
         mMockPackageManager = mock(PackageManager.class);
+        mMockPackageManagerInternal = mock(PackageManagerInternal.class);
         mMockUserManager = mock(UserManager.class);
 
         // Prepare injection values.
@@ -311,7 +395,7 @@
         mInjectedPackageUidMap.put(LAUNCHER_1, LAUNCHER_UID_1);
         mInjectedPackageUidMap.put(LAUNCHER_2, LAUNCHER_UID_2);
 
-        mInjectedFilePathRoot = new File(getContext().getCacheDir(), "test-files");
+        mInjectedFilePathRoot = new File(getTestContext().getCacheDir(), "test-files");
 
         // Empty the data directory.
         if (mInjectedFilePathRoot.exists()) {
@@ -324,6 +408,10 @@
         setCaller(CALLING_PACKAGE_1);
     }
 
+    private Context getTestContext() {
+        return getInstrumentation().getContext();
+    }
+
     /** (Re-) init the manager and the service. */
     private void initService() {
         LocalServices.removeServiceForTest(ShortcutServiceInternal.class);
@@ -427,6 +515,10 @@
                 + "/" + ShortcutService.FILENAME_USER_PACKAGES);
     }
 
+    private void waitOnMainThread() throws Throwable {
+        runTestOnUiThread(() -> {});
+    }
+
     private static Bundle makeBundle(Object... keysAndValues) {
         Preconditions.checkState((keysAndValues.length % 2) == 0);
 
@@ -864,9 +956,9 @@
     }
 
     public void testSetDynamicShortcuts() {
-        final Icon icon1 = Icon.createWithResource(mContext, R.drawable.icon1);
+        final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.icon1);
         final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
-                mContext.getResources(), R.drawable.icon2));
+                getTestContext().getResources(), R.drawable.icon2));
 
         final ShortcutInfo si1 = makeShortcut(
                 "shortcut1",
@@ -907,7 +999,7 @@
         dumpsysOnLogcat();
 
         mInjectedCurrentTimeLillis++; // Need to advance the clock for reset to work.
-        mService.resetThrottlingInner();
+        mService.resetThrottlingInner(UserHandle.USER_SYSTEM);
 
         dumpsysOnLogcat();
 
@@ -1148,16 +1240,16 @@
     }
 
     public void testIcons() {
-        final Icon res32x32 = Icon.createWithResource(mContext, R.drawable.black_32x32);
-        final Icon res64x64 = Icon.createWithResource(mContext, R.drawable.black_64x64);
-        final Icon res512x512 = Icon.createWithResource(mContext, R.drawable.black_512x512);
+        final Icon res32x32 = Icon.createWithResource(getTestContext(), R.drawable.black_32x32);
+        final Icon res64x64 = Icon.createWithResource(getTestContext(), R.drawable.black_64x64);
+        final Icon res512x512 = Icon.createWithResource(getTestContext(), R.drawable.black_512x512);
 
         final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
-                mContext.getResources(), R.drawable.black_32x32));
+                getTestContext().getResources(), R.drawable.black_32x32));
         final Icon bmp64x64 = Icon.createWithBitmap(BitmapFactory.decodeResource(
-                mContext.getResources(), R.drawable.black_64x64));
+                getTestContext().getResources(), R.drawable.black_64x64));
         final Icon bmp512x512 = Icon.createWithBitmap(BitmapFactory.decodeResource(
-                mContext.getResources(), R.drawable.black_512x512));
+                getTestContext().getResources(), R.drawable.black_512x512));
 
         // Set from package 1
         setCaller(CALLING_PACKAGE_1);
@@ -1263,7 +1355,7 @@
     private void checkShrinkBitmap(int expectedWidth, int expectedHeight, int resId, int maxSize) {
         assertBitmapSize(expectedWidth, expectedHeight,
                 ShortcutService.shrinkBitmap(BitmapFactory.decodeResource(
-                        mContext.getResources(), resId),
+                        getTestContext().getResources(), resId),
                         maxSize));
     }
 
@@ -1418,7 +1510,7 @@
         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
             ShortcutInfo s2 = makeShortcutBuilder()
                     .setId("s2")
-                    .setIcon(Icon.createWithResource(mContext, R.drawable.black_32x32))
+                    .setIcon(Icon.createWithResource(getTestContext(), R.drawable.black_32x32))
                     .build();
 
             ShortcutInfo s4 = makeShortcutBuilder()
@@ -1787,6 +1879,125 @@
         // TODO Check extra, etc
     }
 
+    public void testLauncherCallback() throws Throwable {
+        LauncherApps.Callback c0 = mock(LauncherApps.Callback.class);
+
+
+        // Set listeners
+
+        runWithCaller(LAUNCHER_1, USER_0, () -> {
+            mLauncherApps.registerCallback(c0, new Handler(Looper.getMainLooper()));
+        });
+
+        runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
+            assertTrue(mManager.setDynamicShortcuts(Arrays.asList(
+                    makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
+        });
+
+        waitOnMainThread();
+        ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
+        verify(c0).onShortcutsChanged(
+                eq(CALLING_PACKAGE_1),
+                shortcuts.capture(),
+                eq(UserHandle.of(USER_0))
+        );
+        assertShortcutIds(assertAllDynamic(shortcuts.getValue()),
+                "s1", "s2", "s3");
+
+        // From different package.
+        reset(c0);
+        runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
+            assertTrue(mManager.setDynamicShortcuts(Arrays.asList(
+                    makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
+        });
+        waitOnMainThread();
+        shortcuts = ArgumentCaptor.forClass(List.class);
+        verify(c0).onShortcutsChanged(
+                eq(CALLING_PACKAGE_2),
+                shortcuts.capture(),
+                eq(UserHandle.of(USER_0))
+        );
+        assertShortcutIds(assertAllDynamic(shortcuts.getValue()),
+                "s1", "s2", "s3");
+
+        // Different user, callback shouldn't be called.
+        reset(c0);
+        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+            assertTrue(mManager.setDynamicShortcuts(Arrays.asList(
+                    makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
+        });
+        waitOnMainThread();
+        verify(c0, times(0)).onShortcutsChanged(
+                anyString(),
+                any(List.class),
+                any(UserHandle.class)
+        );
+
+        // Test for addDynamicShortcut.
+        reset(c0);
+        runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
+            assertTrue(mManager.addDynamicShortcut(makeShortcut("s4")));
+        });
+
+        waitOnMainThread();
+        shortcuts = ArgumentCaptor.forClass(List.class);
+        verify(c0).onShortcutsChanged(
+                eq(CALLING_PACKAGE_1),
+                shortcuts.capture(),
+                eq(UserHandle.of(USER_0))
+        );
+        assertShortcutIds(assertAllDynamic(shortcuts.getValue()),
+                "s1", "s2", "s3", "s4");
+
+        // Test for remove
+        reset(c0);
+        runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
+            mManager.deleteDynamicShortcut("s1");
+        });
+
+        waitOnMainThread();
+        shortcuts = ArgumentCaptor.forClass(List.class);
+        verify(c0).onShortcutsChanged(
+                eq(CALLING_PACKAGE_1),
+                shortcuts.capture(),
+                eq(UserHandle.of(USER_0))
+        );
+        assertShortcutIds(assertAllDynamic(shortcuts.getValue()),
+                "s2", "s3", "s4");
+
+        // Test for update
+        reset(c0);
+        runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
+            assertTrue(mManager.updateShortcuts(Arrays.asList(
+                    makeShortcut("s1"), makeShortcut("s2"))));
+        });
+
+        waitOnMainThread();
+        shortcuts = ArgumentCaptor.forClass(List.class);
+        verify(c0).onShortcutsChanged(
+                eq(CALLING_PACKAGE_1),
+                shortcuts.capture(),
+                eq(UserHandle.of(USER_0))
+        );
+        assertShortcutIds(assertAllDynamic(shortcuts.getValue()),
+                "s2", "s3", "s4");
+
+        // Test for deleteAll
+        reset(c0);
+        runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
+            mManager.deleteAllDynamicShortcuts();
+        });
+
+        waitOnMainThread();
+        shortcuts = ArgumentCaptor.forClass(List.class);
+        verify(c0).onShortcutsChanged(
+                eq(CALLING_PACKAGE_1),
+                shortcuts.capture(),
+                eq(UserHandle.of(USER_0))
+        );
+        assertEquals(0, shortcuts.getValue().size());
+    }
+
     // === Test for persisting ===
 
     public void testSaveAndLoadUser_empty() {
@@ -1808,9 +2019,9 @@
     public void testSaveAndLoadUser() {
         // First, create some shortcuts and save.
         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
-            final Icon icon1 = Icon.createWithResource(mContext, R.drawable.black_64x16);
+            final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_64x16);
             final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
-                    mContext.getResources(), R.drawable.icon2));
+                    getTestContext().getResources(), R.drawable.icon2));
 
             final ShortcutInfo si1 = makeShortcut(
                     "s1",
@@ -1835,9 +2046,9 @@
             assertEquals(2, mManager.getRemainingCallCount());
         });
         runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
-            final Icon icon1 = Icon.createWithResource(mContext, R.drawable.black_16x64);
+            final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_16x64);
             final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
-                    mContext.getResources(), R.drawable.icon2));
+                    getTestContext().getResources(), R.drawable.icon2));
 
             final ShortcutInfo si1 = makeShortcut(
                     "s1",
@@ -1862,9 +2073,9 @@
             assertEquals(2, mManager.getRemainingCallCount());
         });
         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
-            final Icon icon1 = Icon.createWithResource(mContext, R.drawable.black_64x64);
+            final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_64x64);
             final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
-                    mContext.getResources(), R.drawable.icon2));
+                    getTestContext().getResources(), R.drawable.icon2));
 
             final ShortcutInfo si1 = makeShortcut(
                     "s1",
@@ -1889,6 +2100,9 @@
             assertEquals(2, mManager.getRemainingCallCount());
         });
 
+        mService.getShortcutsForTest().get(UserHandle.USER_SYSTEM).setLauncherComponent(
+                mService, new ComponentName("pkg1", "class"));
+
         // Restore.
         initService();
 
@@ -1918,6 +2132,9 @@
             assertEquals("title2-2", getCallerShortcut("s2").getTitle());
         });
 
+        assertEquals("pkg1", mService.getShortcutsForTest().get(UserHandle.USER_SYSTEM)
+                .getLauncherComponent().getPackageName());
+
         // Start another user
         mService.onStartUserLocked(USER_10);
 
@@ -1932,6 +2149,7 @@
             assertEquals("title10-1-1", getCallerShortcut("s1").getTitle());
             assertEquals("title10-1-2", getCallerShortcut("s2").getTitle());
         });
+        assertNull(mService.getShortcutsForTest().get(USER_10).getLauncherComponent());
 
         // Try stopping the user
         mService.onCleanupUserInner(USER_10);
@@ -1941,4 +2159,8 @@
 
         // TODO Check all other fields
     }
+
+    // TODO Detailed test for hasShortcutPermissionInner().
+
+    // TODO Add tests for the command line functions too.
 }
diff --git a/services/usage/java/com/android/server/usage/AppIdleHistory.java b/services/usage/java/com/android/server/usage/AppIdleHistory.java
index 3e2b43d..a3313c9 100644
--- a/services/usage/java/com/android/server/usage/AppIdleHistory.java
+++ b/services/usage/java/com/android/server/usage/AppIdleHistory.java
@@ -274,6 +274,11 @@
                 - (idle ? mScreenOnTimeThreshold : 0) - 1000 /* just a second more */;
     }
 
+    public void clearUsageLocked(String packageName, int userId) {
+        ArrayMap<String, PackageHistory> userHistory = getUserHistoryLocked(userId);
+        userHistory.remove(packageName);
+    }
+
     private boolean hasPassedThresholdsLocked(PackageHistory packageHistory, long elapsedRealtime) {
         return (packageHistory.lastUsedScreenTime
                     <= getScreenOnTimeLocked(elapsedRealtime) - mScreenOnTimeThreshold)
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 8da1785..beec40f 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -180,6 +180,7 @@
         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");
 
         getContext().registerReceiverAsUser(new PackageReceiver(), UserHandle.ALL, packageFilter,
@@ -266,6 +267,12 @@
                     || Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
                 clearCarrierPrivilegedApps();
             }
+            if ((Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
+                    Intent.ACTION_PACKAGE_ADDED.equals(action))
+                    && !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+                clearAppIdleForPackage(intent.getData().getSchemeSpecificPart(),
+                        getSendingUserId());
+            }
         }
     }
 
@@ -332,6 +339,12 @@
         }
     }
 
+    void clearAppIdleForPackage(String packageName, int userId) {
+        synchronized (mLock) {
+            mAppIdleHistory.clearUsageLocked(packageName, userId);
+        }
+    }
+
     private void cleanUpRemovedUsersLocked() {
         final List<UserInfo> users = mUserManager.getUsers(true);
         if (users == null || users.size() == 0) {
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 10808da..afb7d93 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -95,6 +95,19 @@
     public static final int STATE_DISCONNECTING = 10;
 
     /**
+     * The state of an external call which is in the process of being pulled from a remote device to
+     * the local device.
+     * <p>
+     * A call can only be in this state if the {@link Details#PROPERTY_IS_EXTERNAL_CALL} property
+     * and {@link Details#CAPABILITY_CAN_PULL_CALL} capability are set on the call.
+     * <p>
+     * An {@link InCallService} will only see this state if it has the
+     * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true} in its
+     * manifest.
+     */
+    public static final int STATE_PULLING_CALL = 11;
+
+    /**
      * The key to retrieve the optional {@code PhoneAccount}s Telecom can bundle with its Call
      * extras. Used to pass the phone accounts to display on the front end to the user in order to
      * select phone accounts to (for example) place a call.
@@ -226,8 +239,23 @@
          */
         public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 0x00400000;
 
+        /**
+         * When set for an external call, indicates that this {@code Call} can be pulled from a
+         * remote device to the current device.
+         * <p>
+         * Should only be set on a {@code Call} where {@link #PROPERTY_IS_EXTERNAL_CALL} is set.
+         * <p>
+         * An {@link InCallService} will only see calls with this capability if it has the
+         * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true}
+         * in its manifest.
+         * <p>
+         * See {@link Connection#CAPABILITY_CAN_PULL_CALL} and
+         * {@link Connection#CAPABILITY_IS_EXTERNAL_CALL}.
+         */
+        public static final int CAPABILITY_CAN_PULL_CALL = 0x00800000;
+
         //******************************************************************************************
-        // Next CAPABILITY value: 0x00800000
+        // Next CAPABILITY value: 0x01000000
         //******************************************************************************************
 
         /**
@@ -261,8 +289,25 @@
          */
         public static final int PROPERTY_WORK_CALL = 0x00000020;
 
+        /**
+         * When set, indicates that this {@code Call} does not actually exist locally for the
+         * {@link ConnectionService}.
+         * <p>
+         * Consider, for example, a scenario where a user has two phones with the same phone number.
+         * When a user places a call on one device, the telephony stack can represent that call on
+         * the other device by adding it to the {@link ConnectionService} with the
+         * {@link Connection#CAPABILITY_IS_EXTERNAL_CALL} capability set.
+         * <p>
+         * An {@link InCallService} will only see calls with this property if it has the
+         * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true}
+         * in its manifest.
+         * <p>
+         * See {@link Connection#CAPABILITY_IS_EXTERNAL_CALL}.
+         */
+        public static final int PROPERTY_IS_EXTERNAL_CALL = 0x00000040;
+
         //******************************************************************************************
-        // Next PROPERTY value: 0x00000040
+        // Next PROPERTY value: 0x00000100
         //******************************************************************************************
 
         private final String mTelecomCallId;
@@ -362,6 +407,9 @@
             if (can(capabilities, CAPABILITY_CAN_PAUSE_VIDEO)) {
                 builder.append(" CAPABILITY_CAN_PAUSE_VIDEO");
             }
+            if (can(capabilities, CAPABILITY_CAN_PULL_CALL)) {
+                builder.append(" CAPABILITY_CAN_PULL_CALL");
+            }
             builder.append("]");
             return builder.toString();
         }
@@ -411,6 +459,9 @@
             if (hasProperty(properties, PROPERTY_EMERGENCY_CALLBACK_MODE)) {
                 builder.append(" PROPERTY_EMERGENCY_CALLBACK_MODE");
             }
+            if (hasProperty(properties, PROPERTY_IS_EXTERNAL_CALL)) {
+                builder.append(" PROPERTY_IS_EXTERNAL_CALL");
+            }
             builder.append("]");
             return builder.toString();
         }
@@ -723,6 +774,17 @@
          *          conferenced.
          */
         public void onConferenceableCallsChanged(Call call, List<Call> conferenceableCalls) {}
+
+        /**
+         * Invoked when a call receives an event from its associated {@link Connection}.
+         * <p>
+         * See {@link Connection#sendConnectionEvent(String, Bundle)}.
+         *
+         * @param call The {@code Call} receiving the event.
+         * @param event The event.
+         * @param extras Extras associated with the connection event.
+         */
+        public void onConnectionEvent(Call call, String event, Bundle extras) {}
     }
 
     /**
@@ -889,6 +951,43 @@
     }
 
     /**
+     * Initiates a request to the {@link ConnectionService} to pull an external call to the local
+     * device.
+     * <p>
+     * Calls to this method are ignored if the call does not have the
+     * {@link Call.Details#PROPERTY_IS_EXTERNAL_CALL} property set.
+     * <p>
+     * An {@link InCallService} will only see calls which support this method if it has the
+     * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true}
+     * in its manifest.
+     */
+    public void pullExternalCall() {
+        // If this isn't an external call, ignore the request.
+        if (!mDetails.hasProperty(Details.PROPERTY_IS_EXTERNAL_CALL)) {
+            return;
+        }
+
+        mInCallAdapter.pullExternalCall(mTelecomCallId);
+    }
+
+    /**
+     * Sends a {@code Call} event from this {@code Call} to the associated {@link Connection} in
+     * the {@link ConnectionService}.
+     * <p>
+     * Events are exposed to {@link ConnectionService} implementations via
+     * {@link android.telecom.Connection#onCallEvent(String, Bundle)}.
+     * <p>
+     * No assumptions should be made as to how a {@link ConnectionService} will handle these events.
+     * Events should be fully qualified (e.g., com.example.event.MY_EVENT) to avoid conflicts.
+     *
+     * @param event The connection event.
+     * @param extras Bundle containing extra information associated with the event.
+     */
+    public void sendCallEvent(String event, Bundle extras) {
+        mInCallAdapter.sendCallEvent(mTelecomCallId, event, extras);
+    }
+
+    /**
      * Obtains the parent of this {@code Call} in a conference, if any.
      *
      * @return The parent {@code Call}, or {@code null} if this {@code Call} is not a
@@ -1211,6 +1310,11 @@
         }
     }
 
+    /** {@hide} */
+    final void internalOnConnectionEvent(String event, Bundle extras) {
+        fireOnConnectionEvent(event, extras);
+    }
+
     private void fireStateChanged(final int newState) {
         for (CallbackRecord<Callback> record : mCallbackRecords) {
             final Call call = this;
@@ -1358,6 +1462,27 @@
     }
 
     /**
+     * Notifies listeners of an incoming connection event.
+     * <p>
+     * Connection events are issued via {@link Connection#sendConnectionEvent(String, Bundle)}.
+     *
+     * @param event
+     * @param extras
+     */
+    private void fireOnConnectionEvent(final String event, final Bundle extras) {
+        for (CallbackRecord<Callback> record : mCallbackRecords) {
+            final Call call = this;
+            final Callback callback = record.getCallback();
+            record.getHandler().post(new Runnable() {
+                @Override
+                public void run() {
+                    callback.onConnectionEvent(call, event, extras);
+                }
+            });
+        }
+    }
+
+    /**
      * Determines if two bundles are equal.
      *
      * @param bundle The original bundle.
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 4547c6a..51a6588 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -93,6 +93,15 @@
     public static final int STATE_DISCONNECTED = 6;
 
     /**
+     * The state of an external connection which is in the process of being pulled from a remote
+     * device to the local device.
+     * <p>
+     * A connection can only be in this state if the {@link #CAPABILITY_IS_EXTERNAL_CALL} and
+     * {@link #CAPABILITY_CAN_PULL_CALL} capability bits are set on the connection.
+     */
+    public static final int STATE_PULLING_CALL = 7;
+
+    /**
      * Connection can currently be put on hold or unheld. This is distinct from
      * {@link #CAPABILITY_SUPPORT_HOLD} in that although a connection may support 'hold' most times,
      * it does not at the moment support the function. This can be true while the call is in the
@@ -251,7 +260,6 @@
     /**
      * Indicates that the connection itself wants to handle any sort of reply response, rather than
      * relying on SMS.
-     * @hide
      */
     public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 0x00400000;
 
@@ -270,8 +278,33 @@
      */
     public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 0x00800000;
 
+    /**
+     * When set, indicates that the {@code Connection} does not actually exist locally for the
+     * {@link ConnectionService}.
+     * <p>
+     * Consider, for example, a scenario where a user has two devices with the same phone number.
+     * When a user places a call on one devices, the telephony stack can represent that call on the
+     * other device by adding is to the {@link ConnectionService} with the
+     * {@code CAPABILITY_IS_EXTERNAL_CALL} capability set.
+     * <p>
+     * An {@link ConnectionService} should not assume that all {@link InCallService}s will handle
+     * external connections.  Only those {@link InCallService}s which have the
+     * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true} in its
+     * manifest will see external connections.
+     */
+    public static final int CAPABILITY_IS_EXTERNAL_CALL = 0x01000000;
+
+    /**
+     * When set for an external connection, indicates that this {@code Connection} can be pulled
+     * from a remote device to the current device.
+     * <p>
+     * Should only be set on a {@code Connection} where {@link #CAPABILITY_IS_EXTERNAL_CALL}
+     * is set.
+     */
+    public static final int CAPABILITY_CAN_PULL_CALL = 0x02000000;
+
     //**********************************************************************************************
-    // Next CAPABILITY value: 0x01000000
+    // Next CAPABILITY value: 0x04000000
     //**********************************************************************************************
 
     /**
@@ -315,6 +348,18 @@
     public static final String EVENT_ON_HOLD_TONE_END =
             "android.telecom.event.ON_HOLD_TONE_END";
 
+    /**
+     * Connection event used to inform {@link InCallService}s when pulling of an external call has
+     * failed.  The user interface should inform the user of the error.
+     * <p>
+     * Expected to be used by the {@link ConnectionService} when the {@link Call#pullExternalCall()}
+     * API is called on a {@link Call} with the properties
+     * {@link Call.Details#PROPERTY_IS_EXTERNAL_CALL} and
+     * {@link Call.Details#CAPABILITY_CAN_PULL_CALL}, but the {@link ConnectionService} could not
+     * pull the external call due to an error condition.
+     */
+    public static final String EVENT_CALL_PULL_FAILED = "android.telecom.event.CALL_PULL_FAILED";
+
     // Flag controlling whether PII is emitted into the logs
     private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
 
@@ -434,6 +479,12 @@
         if (can(capabilities, CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION)) {
             builder.append(" CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION");
         }
+        if (can(capabilities, CAPABILITY_IS_EXTERNAL_CALL)) {
+            builder.append(" CAPABILITY_IS_EXTERNAL_CALL");
+        }
+        if (can(capabilities, CAPABILITY_CAN_PULL_CALL)) {
+            builder.append(" CAPABILITY_CAN_PULL_CALL");
+        }
 
         builder.append("]");
         return builder.toString();
@@ -465,8 +516,7 @@
         public void onConferenceStarted() {}
         public void onConferenceMergeFailed(Connection c) {}
         public void onExtrasChanged(Connection c, Bundle extras) {}
-        /** @hide */
-        public void onConnectionEvent(Connection c, String event) {}
+        public void onConnectionEvent(Connection c, String event, Bundle extras) {}
     }
 
     /**
@@ -1836,9 +1886,8 @@
     public void onReject() {}
 
     /**
-     * Notifies ths Connection of a request reject with a message.
-     *
-     * @hide
+     * Notifies this Connection, which is in {@link #STATE_RINGING}, of
+     * a request to reject with a message.
      */
     public void onReject(String replyMessage) {}
 
@@ -1854,6 +1903,31 @@
      */
     public void onPostDialContinue(boolean proceed) {}
 
+    /**
+     * Notifies this Connection of a request to pull an external call to the local device.
+     * <p>
+     * The {@link InCallService} issues a request to pull an external call to the local device via
+     * {@link Call#pullExternalCall()}.
+     * <p>
+     * For a Connection to be pulled, both the {@link Connection#CAPABILITY_CAN_PULL_CALL} and
+     * {@link Connection#CAPABILITY_IS_EXTERNAL_CALL} capability bits must be set.
+     * <p>
+     * For more information on external calls, see {@link Connection#CAPABILITY_IS_EXTERNAL_CALL}.
+     */
+    public void onPullExternalCall() {}
+
+    /**
+     * Notifies this Connection of a {@link Call} event initiated from an {@link InCallService}.
+     * <p>
+     * The {@link InCallService} issues a Call event via {@link Call#sendCallEvent(String, Bundle)}.
+     * <p>
+     * See also {@link Call#sendCallEvent(String, Bundle)}.
+     *
+     * @param event The call event.
+     * @param extras Extras associated with the call event.
+     */
+    public void onCallEvent(String event, Bundle extras) {}
+
     static String toLogSafePhoneNumber(String number) {
         // For unknown number, log empty string.
         if (number == null) {
@@ -2008,14 +2082,20 @@
     }
 
     /**
-     * Sends a connection event to Telecom.
+     * Sends an event associated with this {@code Connection}, with associated event extras.
+     *
+     * Events are exposed to {@link InCallService} implementations via the
+     * {@link Call.Callback#onConnectionEvent(Call, String, Bundle)} API.
+     *
+     * No assumptions should be made as to how an In-Call UI or service will handle these events.
+     * Events should be fully qualified (e.g., com.example.event.MY_EVENT) to avoid conflicts.
      *
      * @param event The connection event.
-     * @hide
+     * @param extras Bundle containing extra information associated with the event.
      */
-    protected void sendConnectionEvent(String event) {
+    public void sendConnectionEvent(String event, Bundle extras) {
         for (Listener l : mListeners) {
-            l.onConnectionEvent(this, event);
+            l.onConnectionEvent(this, event, null);
         }
     }
 }
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 5b62e03..d18b317 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -103,6 +103,8 @@
     private static final int MSG_SWAP_CONFERENCE = 19;
     private static final int MSG_REJECT_WITH_MESSAGE = 20;
     private static final int MSG_SILENCE = 21;
+    private static final int MSG_PULL_EXTERNAL_CALL = 22;
+    private static final int MSG_SEND_CALL_EVENT = 23;
 
     private static Connection sNullConnection;
 
@@ -245,6 +247,20 @@
             args.argi1 = proceed ? 1 : 0;
             mHandler.obtainMessage(MSG_ON_POST_DIAL_CONTINUE, args).sendToTarget();
         }
+
+        @Override
+        public void pullExternalCall(String callId) {
+            mHandler.obtainMessage(MSG_PULL_EXTERNAL_CALL, callId).sendToTarget();
+        }
+
+        @Override
+        public void sendCallEvent(String callId, String event, Bundle extras) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = event;
+            args.arg3 = extras;
+            mHandler.obtainMessage(MSG_SEND_CALL_EVENT, args).sendToTarget();
+        }
     };
 
     private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@@ -382,6 +398,22 @@
                     }
                     break;
                 }
+                case MSG_PULL_EXTERNAL_CALL: {
+                    pullExternalCall((String) msg.obj);
+                    break;
+                }
+                case MSG_SEND_CALL_EVENT: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        String callId = (String) args.arg1;
+                        String event = (String) args.arg2;
+                        Bundle extras = (Bundle) args.arg3;
+                        sendCallEvent(callId, event, extras);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
                 default:
                     break;
             }
@@ -615,10 +647,10 @@
         }
 
         @Override
-        public void onConnectionEvent(Connection connection, String event) {
+        public void onConnectionEvent(Connection connection, String event, Bundle extras) {
             String id = mIdByConnection.get(connection);
             if (id != null) {
-                mAdapter.onConnectionEvent(id, event);
+                mAdapter.onConnectionEvent(id, event, extras);
             }
         }
     };
@@ -864,6 +896,39 @@
         }
     }
 
+    /**
+     * Notifies a {@link Connection} of a request to pull an external call.
+     *
+     * See {@link Call#pullExternalCall()}.
+     *
+     * @param callId The ID of the call to pull.
+     */
+    private void pullExternalCall(String callId) {
+        Log.d(this, "pullExternalCall(%s)", callId);
+        Connection connection = findConnectionForAction(callId, "pullExternalCall");
+        if (connection != null) {
+            connection.onPullExternalCall();
+        }
+    }
+
+    /**
+     * Notifies a {@link Connection} of a call event.
+     *
+     * See {@link Call#sendCallEvent(String, Bundle)}.
+     *
+     * @param callId The ID of the call receiving the event.
+     * @param event The event.
+     * @param extras Extras associated with the event.
+     */
+    private void sendCallEvent(String callId, String event, Bundle extras) {
+        Log.d(this, "sendCallEvent(%s, %s)", callId, event);
+        Connection connection = findConnectionForAction(callId, "sendCallEvent");
+        if (connection != null) {
+            connection.onCallEvent(event, extras);
+        }
+
+    }
+
     private void onPostDialContinue(String callId, boolean proceed) {
         Log.d(this, "onPostDialContinue(%s)", callId);
         findConnectionForAction(callId, "stopDtmfTone").onPostDialContinue(proceed);
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapter.java b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
index 30fc5ad..e91128f 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
@@ -418,12 +418,13 @@
      *
      * @param callId The unique ID of the call.
      * @param event The event.
+     * @param extras Extras associated with the event.
      */
-    void onConnectionEvent(String callId, String event) {
+    void onConnectionEvent(String callId, String event, Bundle extras) {
         Log.v(this, "onConnectionEvent: %s", event);
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.onConnectionEvent(callId, event);
+                adapter.onConnectionEvent(callId, event, extras);
             } catch (RemoteException ignored) {
             }
         }
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
index 6a8c1cb..4b15e54 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
@@ -245,7 +245,8 @@
                 case MSG_ON_CONNECTION_EVENT: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.onConnectionEvent((String) args.arg1, (String) args.arg2);
+                        mDelegate.onConnectionEvent((String) args.arg1, (String) args.arg2,
+                                (Bundle) args.arg3);
                     } finally {
                         args.recycle();
                     }
@@ -432,10 +433,11 @@
         }
 
         @Override
-        public final void onConnectionEvent(String connectionId, String event) {
+        public final void onConnectionEvent(String connectionId, String event, Bundle extras) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = connectionId;
             args.arg2 = event;
+            args.arg3 = extras;
             mHandler.obtainMessage(MSG_ON_CONNECTION_EVENT, args).sendToTarget();
         }
     };
diff --git a/telecomm/java/android/telecom/DisconnectCause.java b/telecomm/java/android/telecom/DisconnectCause.java
index 2eef7ee..cf73d4f 100644
--- a/telecomm/java/android/telecom/DisconnectCause.java
+++ b/telecomm/java/android/telecom/DisconnectCause.java
@@ -64,6 +64,17 @@
      */
     public static final int CONNECTION_MANAGER_NOT_SUPPORTED = 10;
 
+    /**
+     * Disconnected because the user did not locally answer the incoming call, but it was answered
+     * on another device where the call was ringing.
+     */
+    public static final int ANSWERED_ELSEWHERE = 11;
+
+    /**
+     * Disconnected because the call was pulled from the current device to another device.
+     */
+    public static final int CALL_PULLED = 12;
+
     private int mDisconnectCode;
     private CharSequence mDisconnectLabel;
     private CharSequence mDisconnectDescription;
diff --git a/telecomm/java/android/telecom/InCallAdapter.java b/telecomm/java/android/telecom/InCallAdapter.java
index 0cf7212b..52ef4a7 100644
--- a/telecomm/java/android/telecom/InCallAdapter.java
+++ b/telecomm/java/android/telecom/InCallAdapter.java
@@ -16,6 +16,7 @@
 
 package android.telecom;
 
+import android.os.Bundle;
 import android.os.RemoteException;
 
 import com.android.internal.telecom.IInCallAdapter;
@@ -251,6 +252,32 @@
     }
 
     /**
+     * Instructs Telecom to pull an external call to the local device.
+     *
+     * @param callId The callId to pull.
+     */
+    public void pullExternalCall(String callId) {
+        try {
+            mAdapter.pullExternalCall(callId);
+        } catch (RemoteException ignored) {
+        }
+    }
+
+    /**
+     * Intructs Telecom to send a call event.
+     *
+     * @param callId The callId to send the event for.
+     * @param event The event.
+     * @param extras Extras associated with the event.
+     */
+    public void sendCallEvent(String callId, String event, Bundle extras) {
+        try {
+            mAdapter.sendCallEvent(callId, event, extras);
+        } catch (RemoteException ignored) {
+        }
+    }
+
+    /**
      * Instructs Telecom to turn the proximity sensor on.
      */
     public void turnProximitySensorOn() {
diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java
index 671399b..df6715d 100644
--- a/telecomm/java/android/telecom/InCallService.java
+++ b/telecomm/java/android/telecom/InCallService.java
@@ -22,6 +22,7 @@
 import android.content.Intent;
 import android.hardware.camera2.CameraManager;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -74,6 +75,7 @@
     private static final int MSG_BRING_TO_FOREGROUND = 6;
     private static final int MSG_ON_CAN_ADD_CALL_CHANGED = 7;
     private static final int MSG_SILENCE_RINGER = 8;
+    private static final int MSG_ON_CONNECTION_EVENT = 9;
 
     /** Default Handler used to consolidate binder method calls onto a single thread. */
     private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@@ -118,6 +120,18 @@
                 case MSG_SILENCE_RINGER:
                     mPhone.internalSilenceRinger();
                     break;
+                case MSG_ON_CONNECTION_EVENT: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        String callId = (String) args.arg1;
+                        String event = (String) args.arg2;
+                        Bundle extras = (Bundle) args.arg3;
+                        mPhone.internalOnConnectionEvent(callId, event, extras);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
                 default:
                     break;
             }
@@ -174,6 +188,15 @@
         public void silenceRinger() {
             mHandler.obtainMessage(MSG_SILENCE_RINGER).sendToTarget();
         }
+
+        @Override
+        public void onConnectionEvent(String callId, String event, Bundle extras) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = event;
+            args.arg3 = extras;
+            mHandler.obtainMessage(MSG_ON_CONNECTION_EVENT, args).sendToTarget();
+        }
     }
 
     private Phone.Listener mPhoneListener = new Phone.Listener() {
@@ -426,6 +449,19 @@
     }
 
     /**
+     * Called when a {@link Call} has received a connection event issued by the
+     * {@link ConnectionService}.
+     * <p>
+     * See {@link Connection#sendConnectionEvent(String, Bundle)}.
+     *
+     * @param call The call the event is associated with.
+     * @param event The event.
+     * @param extras Any associated extras.
+     */
+    public void onConnectionEvent(Call call, String event, Bundle extras) {
+    }
+
+    /**
      * Used to issue commands to the {@link Connection.VideoProvider} associated with a
      * {@link Call}.
      */
diff --git a/telecomm/java/android/telecom/Phone.java b/telecomm/java/android/telecom/Phone.java
index d45938c..a4ef560 100644
--- a/telecomm/java/android/telecom/Phone.java
+++ b/telecomm/java/android/telecom/Phone.java
@@ -17,6 +17,7 @@
 package android.telecom;
 
 import android.annotation.SystemApi;
+import android.os.Bundle;
 import android.util.ArrayMap;
 
 import java.util.Collections;
@@ -190,6 +191,13 @@
         fireSilenceRinger();
     }
 
+    final void internalOnConnectionEvent(String telecomId, String event, Bundle extras) {
+        Call call = mCallByTelecomCallId.get(telecomId);
+        if (call != null) {
+            call.internalOnConnectionEvent(event, extras);
+        }
+    }
+
     /**
      * Called to destroy the phone and cleanup any lingering calls.
      */
diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java
index 0185808..5b602eb 100644
--- a/telecomm/java/android/telecom/RemoteConnection.java
+++ b/telecomm/java/android/telecom/RemoteConnection.java
@@ -212,12 +212,14 @@
 
         /**
          * Handles a connection event propagated to this {@link RemoteConnection}.
+         * <p>
+         * Connection events originate from {@link Connection#sendConnectionEvent(String, Bundle)}.
          *
          * @param connection The {@code RemoteConnection} invoking this method.
          * @param event The connection event.
-         * @hide
+         * @param extras Extras associated with the event.
          */
-        public void onConnectionEvent(RemoteConnection connection, String event) {}
+        public void onConnectionEvent(RemoteConnection connection, String event, Bundle extras) {}
     }
 
     /**
@@ -962,6 +964,20 @@
     }
 
     /**
+     * Instructs this {@link RemoteConnection} to pull itself to the local device.
+     * <p>
+     * See {@link Call#pullExternalCall()} for more information.
+     */
+    public void pullExternalCall() {
+        try {
+            if (mConnected) {
+                mConnectionService.pullExternalCall(mConnectionId);
+            }
+        } catch (RemoteException ignored) {
+        }
+    }
+
+    /**
      * Set the audio state of this {@code RemoteConnection}.
      *
      * @param state The audio state of this {@code RemoteConnection}.
@@ -1301,14 +1317,14 @@
     }
 
     /** @hide */
-    void onConnectionEvent(final String event) {
+    void onConnectionEvent(final String event, final Bundle extras) {
         for (CallbackRecord record : mCallbackRecords) {
             final RemoteConnection connection = this;
             final Callback callback = record.getCallback();
             record.getHandler().post(new Runnable() {
                 @Override
                 public void run() {
-                    callback.onConnectionEvent(connection, event);
+                    callback.onConnectionEvent(connection, event, extras);
                 }
             });
         }
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index b85382f..fa7183a 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -332,9 +332,10 @@
         }
 
         @Override
-        public void onConnectionEvent(String callId, String event) {
+        public void onConnectionEvent(String callId, String event, Bundle extras) {
             if (mConnectionById.containsKey(callId)) {
-                findConnectionForAction(callId, "onConnectionEvent").onConnectionEvent(event);
+                findConnectionForAction(callId, "onConnectionEvent").onConnectionEvent(event,
+                        extras);
             }
         }
     };
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 8afb455..4fa8fe9 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -317,6 +317,18 @@
             "android.telecom.IN_CALL_SERVICE_RINGING";
 
     /**
+     * A boolean meta-data value indicating whether an {@link InCallService} wants to be informed of
+     * calls which have the {@link Call.Details#PROPERTY_IS_EXTERNAL_CALL} property.  An external
+     * call is one which a {@link ConnectionService} knows about, but is not connected to directly.
+     * Dialer implementations (see {@link #getDefaultDialerPackage()}) which would like to be
+     * informed of external calls should set this meta-data to {@code true} in the manifest
+     * registration of their {@link InCallService}.  By default, the {@link InCallService} will NOT
+     * be informed of external calls.
+     */
+    public static final String METADATA_INCLUDE_EXTERNAL_CALLS =
+            "android.telecom.INCLUDE_EXTERNAL_CALLS";
+
+    /**
      * The dual tone multi-frequency signaling character sent to indicate the dialing system should
      * pause for a predefined period.
      */
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
index 8a54add..3ee0e9f 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
@@ -75,4 +75,8 @@
     void swapConference(String conferenceCallId);
 
     void onPostDialContinue(String callId, boolean proceed);
+
+    void pullExternalCall(String callId);
+
+    void sendCallEvent(String callId, String event, in Bundle extras);
 }
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
index 569c244..dff1b11 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
@@ -87,5 +87,5 @@
 
     void setExtras(String callId, in Bundle extras);
 
-    void onConnectionEvent(String callId, String event);
+    void onConnectionEvent(String callId, String event, in Bundle extras);
 }
diff --git a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl
index 863fff2..0678fe2 100644
--- a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl
@@ -16,6 +16,7 @@
 
 package com.android.internal.telecom;
 
+import android.os.Bundle;
 import android.telecom.PhoneAccountHandle;
 
 /**
@@ -60,4 +61,8 @@
     void turnOnProximitySensor();
 
     void turnOffProximitySensor(boolean screenOnImmediately);
+
+    void pullExternalCall(String callId);
+
+    void sendCallEvent(String callId, String event, in Bundle extras);
 }
diff --git a/telecomm/java/com/android/internal/telecom/IInCallService.aidl b/telecomm/java/com/android/internal/telecom/IInCallService.aidl
index 0088e0c..3e43fe2 100644
--- a/telecomm/java/com/android/internal/telecom/IInCallService.aidl
+++ b/telecomm/java/com/android/internal/telecom/IInCallService.aidl
@@ -17,6 +17,7 @@
 package com.android.internal.telecom;
 
 import android.app.PendingIntent;
+import android.os.Bundle;
 import android.telecom.CallAudioState;
 import android.telecom.ParcelableCall;
 
@@ -47,4 +48,6 @@
     void onCanAddCallChanged(boolean canAddCall);
 
     void silenceRinger();
+
+    void onConnectionEvent(String callId, String event, in Bundle extras);
 }
diff --git a/telephony/java/com/android/ims/ImsExternalCallState.aidl b/telephony/java/com/android/ims/ImsExternalCallState.aidl
new file mode 100644
index 0000000..c208702
--- /dev/null
+++ b/telephony/java/com/android/ims/ImsExternalCallState.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2016 The Android Open Source 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.ims;
+
+parcelable ImsExternalCallState;
diff --git a/telephony/java/com/android/ims/ImsExternalCallState.java b/telephony/java/com/android/ims/ImsExternalCallState.java
new file mode 100644
index 0000000..edb6bfc
--- /dev/null
+++ b/telephony/java/com/android/ims/ImsExternalCallState.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2016 The Android Open Source 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.ims;
+
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.Rlog;
+
+/*
+ * This file contains all the api's through which
+ * information received in Dialog Event Package can be
+ * queried
+ */
+
+/**
+ * Parcelable object to handle VICE Dialog Information
+ * @hide
+ */
+public class ImsExternalCallState implements Parcelable {
+
+    private static final String TAG = "ImsExternalCallState";
+
+    // Dialog States
+    public static final int CALL_STATE_CONFIRMED = 1;
+    public static final int CALL_STATE_TERMINATED = 2;
+    // Dialog Id
+    public int mCallId;
+    // Number
+    public Uri mAddress;
+    public boolean mIsPullable;
+    // CALL_STATE_CONFIRMED / CALL_STATE_TERMINATED
+    public int mCallState;
+    // ImsCallProfile#CALL_TYPE_*
+    public int mCallType;
+    public boolean mIsHeld;
+
+    public ImsExternalCallState() {
+    }
+
+    public ImsExternalCallState(Parcel in) {
+        mCallId = in.readInt();
+        ClassLoader classLoader = ImsExternalCallState.class.getClassLoader();
+        mAddress = in.readParcelable(classLoader);
+        mIsPullable = (in.readInt() != 0);
+        mCallState = in.readInt();
+        mCallType = in.readInt();
+        mIsHeld = (in.readInt() != 0);
+        Rlog.d(TAG, "ImsExternalCallState const = " +
+                "callid = " + getCallId() +
+                ", address = " + getAddress() +
+                ", mCallState = " + getCallState() +
+                ", calltype = " + getCallType() +
+                ", isheld = " + isCallHeld());
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mCallId);
+        out.writeParcelable(mAddress, 0);
+        out.writeInt(mIsPullable ? 1 : 0);
+        out.writeInt(mCallState);
+        out.writeInt(mCallType);
+        out.writeInt(mIsHeld ? 1 : 0);
+    }
+
+    public static final Parcelable.Creator<ImsExternalCallState> CREATOR =
+            new Parcelable.Creator<ImsExternalCallState>() {
+        @Override
+        public ImsExternalCallState createFromParcel(Parcel in) {
+            return new ImsExternalCallState(in);
+        }
+
+        @Override
+        public ImsExternalCallState[] newArray(int size) {
+            return new ImsExternalCallState[size];
+        }
+    };
+
+    public int getCallId() {
+        return mCallId;
+    }
+
+    public Uri getAddress() {
+        return mAddress;
+    }
+
+    public boolean isCallPullable() {
+        return mIsPullable;
+    }
+
+    public int getCallState() {
+        return mCallState;
+    }
+
+    public int getCallType() {
+        return mCallType;
+    }
+
+    public boolean isCallHeld() {
+        return mIsHeld;
+    }
+
+    @Override
+    public String toString() {
+        return "ImsExternalCallState { mCallId = " + mCallId +
+                ", mAddress = " + mAddress +
+                ", mIsPullable = " + mIsPullable +
+                ", mCallState = " + mCallState +
+                ", mCallType = " + mCallType +
+                ", mIsHeld = " + mIsHeld + "}";
+    }
+}
diff --git a/telephony/java/com/android/ims/ImsReasonInfo.java b/telephony/java/com/android/ims/ImsReasonInfo.java
index 558c1dc..f06d154 100644
--- a/telephony/java/com/android/ims/ImsReasonInfo.java
+++ b/telephony/java/com/android/ims/ImsReasonInfo.java
@@ -241,12 +241,12 @@
     public static final int CODE_ANSWERED_ELSEWHERE = 1014;
 
     /**
-     * Call pull request failure from the network.
+     * For MultiEndpoint - Call Pull request has failed
      */
     public static final int CODE_CALL_PULL_OUT_OF_SYNC = 1015;
 
     /**
-     * Call ended due to being pulled onto another device.
+     * For MultiEndpoint - Call has been pulled from primary to secondary
      */
     public static final int CODE_CALL_END_CAUSE_CALL_PULL = 1016;
 
diff --git a/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl b/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl
new file mode 100644
index 0000000..70a474e
--- /dev/null
+++ b/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 The Android Open Source 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.ims.internal;
+
+import com.android.ims.ImsExternalCallState;
+
+/**
+ * A listener type for receiving notifications about DEP through IMS
+ *
+ * {@hide}
+ */
+interface IImsExternalCallStateListener {
+
+    /**
+     * Notifies client when Dialog Event Package update is received
+     *
+     * @param List<ImsExternalCallState> - External Call Dialog
+     *
+     * @return void.
+     */
+    void notifyRefreshExternalCallState(in List<ImsExternalCallState> externalCallDialogs);
+
+}
+
diff --git a/telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl b/telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl
new file mode 100644
index 0000000..1bfb9b2
--- /dev/null
+++ b/telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 The Android Open Source 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.ims.internal;
+
+import com.android.ims.internal.IImsExternalCallStateListener;
+
+/**
+ * Provides the ImsMultiEndpoint interface
+ *
+ * {@hide}
+ */
+interface IImsMultiEndpoint {
+    /**
+     * Sets the listener.
+     */
+    void setListener(in IImsExternalCallStateListener listener);
+
+
+    /**
+     * Query api to get the latest Dialog Event Package information
+     * Should be invoked only after setListener is done
+     */
+    void requestDialogEventPackageState();
+}
diff --git a/telephony/java/com/android/ims/internal/IImsService.aidl b/telephony/java/com/android/ims/internal/IImsService.aidl
index 30c48d7..a9614a6 100644
--- a/telephony/java/com/android/ims/internal/IImsService.aidl
+++ b/telephony/java/com/android/ims/internal/IImsService.aidl
@@ -19,12 +19,13 @@
 import android.app.PendingIntent;
 
 import com.android.ims.ImsCallProfile;
-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;
+import com.android.ims.internal.IImsEcbm;
+import com.android.ims.internal.IImsMultiEndpoint;
+import com.android.ims.internal.IImsRegistrationListener;
+import com.android.ims.internal.IImsUt;
 
 import android.os.Message;
 
@@ -75,4 +76,9 @@
      * Used to set current TTY Mode.
      */
     void setUiTTYMode(int serviceId, int uiTtyMode, in Message onComplete);
+
+    /**
+     * MultiEndpoint interface for DEP.
+     */
+    IImsMultiEndpoint getMultiEndpointInterface(int serviceId);
 }
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 7f90731..4f0e036 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -97,6 +97,12 @@
     int NETWORK_REJECT = 53;                  /* Request is rejected by network */
     int OPERATION_NOT_ALLOWED = 54;           /* Not allowed the request now */
     int EMPTY_RECORD = 55;                    /* The request record is empty */
+    int INVALID_SMS_FORMAT = 56;              /* Invalid sms format */
+    int ENCODING_ERR = 57;                    /* Message not encoded properly */
+    int INVALID_SMSC_ADDRESS = 58;            /* SMSC address specified is invalid */
+    int NO_SUCH_ENTRY = 59;                   /* No such entry present to perform the request */
+    int NETWORK_NOT_READY = 60;               /* Network is not ready to perform the request */
+    int NOT_PROVISIONED = 61;                 /* Device doesnot have this value provisioned */
     // Below is list of OEM specific error codes which can by used by OEMs in case they don't want to
     // reveal particular replacement for Generic failure
     int OEM_ERROR_1 = 501;
diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
index 645c3a1..ea3b5c9 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
@@ -217,4 +217,12 @@
      *     or Earpiece, based on the default audio routing strategy.
      */
     static final String PROPERTY_VIDEOCALL_AUDIO_OUTPUT = "persist.radio.call.audio.output";
+
+    /**
+     * For MultiEndpoint Feature
+     * If true: Dial intent is for call pull functionality
+     * if false: normal dial
+     */
+    static final String EXTRA_IS_CALL_PULL =
+            "android.telephony.extra.IS_CALL_PULL";
 }
diff --git a/tests/SoundTriggerTests/Android.mk b/tests/SoundTriggerTests/Android.mk
index ac562b9..e67134d 100644
--- a/tests/SoundTriggerTests/Android.mk
+++ b/tests/SoundTriggerTests/Android.mk
@@ -27,6 +27,7 @@
   LOCAL_SRC_FILES := src/android/hardware/soundtrigger/SoundTriggerTest.java
 endif
 
+LOCAL_STATIC_JAVA_LIBRARIES := mockito-target
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
 LOCAL_PACKAGE_NAME := SoundTriggerTests
diff --git a/tests/SoundTriggerTests/AndroidManifest.xml b/tests/SoundTriggerTests/AndroidManifest.xml
index e8b9dd3..f7454c7 100644
--- a/tests/SoundTriggerTests/AndroidManifest.xml
+++ b/tests/SoundTriggerTests/AndroidManifest.xml
@@ -17,7 +17,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.hardware.soundtrigger">
     <uses-permission android:name="android.permission.MANAGE_SOUND_TRIGGER" />
-
+    <uses-permission android:name="android.permission.INTERNET" />
+    
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
diff --git a/tests/SoundTriggerTests/src/android/hardware/soundtrigger/stubhal/GenericSoundModelTest.java b/tests/SoundTriggerTests/src/android/hardware/soundtrigger/stubhal/GenericSoundModelTest.java
index 7acb472..ad02d2b 100644
--- a/tests/SoundTriggerTests/src/android/hardware/soundtrigger/stubhal/GenericSoundModelTest.java
+++ b/tests/SoundTriggerTests/src/android/hardware/soundtrigger/stubhal/GenericSoundModelTest.java
@@ -16,70 +16,180 @@
 
 package android.hardware.soundtrigger;
 
-import java.util.Random;
-import java.util.UUID;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
 
 import android.content.Context;
+import android.hardware.soundtrigger.SoundTrigger.GenericRecognitionEvent;
 import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
+import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionEvent;
+import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
 import android.media.soundtrigger.SoundTriggerManager;
 import android.os.ParcelUuid;
 import android.os.ServiceManager;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.internal.app.ISoundTriggerService;
 
-import java.util.Arrays;
+import java.io.DataOutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.ArrayList;
 import java.util.Random;
 import java.util.UUID;
 
+import org.mockito.MockitoAnnotations;
+
 public class GenericSoundModelTest extends AndroidTestCase {
-    private Random mRandom = new Random();
+    static final int MSG_DETECTION_ERROR = -1;
+    static final int MSG_DETECTION_RESUME = 0;
+    static final int MSG_DETECTION_PAUSE = 1;
+    static final int MSG_KEYPHRASE_TRIGGER = 2;
+    static final int MSG_GENERIC_TRIGGER = 4;
+
+    private Random random = new Random();
+    private ArrayList<UUID> loadedModelUuids;
+    private ISoundTriggerService soundTriggerService;
+    private SoundTriggerManager soundTriggerManager;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        MockitoAnnotations.initMocks(this);
+
+        Context context = getContext();
+        soundTriggerService = ISoundTriggerService.Stub.asInterface(
+                ServiceManager.getService(Context.SOUND_TRIGGER_SERVICE));
+        soundTriggerManager = (SoundTriggerManager) context.getSystemService(
+                Context.SOUND_TRIGGER_SERVICE);
+
+        loadedModelUuids = new ArrayList<UUID>();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        for (UUID modelUuid : loadedModelUuids) {
+            soundTriggerService.deleteSoundModel(new ParcelUuid(modelUuid));
+        }
+        super.tearDown();
+    }
+
+    GenericSoundModel new_sound_model() {
+        // Create sound model
+        byte[] data = new byte[1024];
+        random.nextBytes(data);
+        UUID modelUuid = UUID.randomUUID();
+        UUID mVendorUuid = UUID.randomUUID();
+        return new GenericSoundModel(modelUuid, mVendorUuid, data);
+    }
 
     @SmallTest
     public void testUpdateGenericSoundModel() throws Exception {
-        Context context = getContext();
-        ISoundTriggerService mSoundTriggerService = ISoundTriggerService.Stub.asInterface(
-            ServiceManager.getService(Context.SOUND_TRIGGER_SERVICE));
-        SoundTriggerManager mSoundTriggerManager = (SoundTriggerManager) context.getSystemService(
-            Context.SOUND_TRIGGER_SERVICE);
+        GenericSoundModel model = new_sound_model();
 
-        byte[] data = new byte[1024];
-        mRandom.nextBytes(data);
-        UUID modelUuid = UUID.randomUUID();
-        UUID mVendorUuid = UUID.randomUUID();
-        GenericSoundModel model = new GenericSoundModel(modelUuid, mVendorUuid, data);
+        // Update sound model
+        soundTriggerService.updateSoundModel(model);
+        loadedModelUuids.add(model.uuid);
 
-        mSoundTriggerService.updateSoundModel(model);
+        // Confirm it was updated
         GenericSoundModel returnedModel =
-            mSoundTriggerService.getSoundModel(new ParcelUuid(modelUuid));
-
+                soundTriggerService.getSoundModel(new ParcelUuid(model.uuid));
         assertEquals(model, returnedModel);
-
-        // Cleanup sound model
-        mSoundTriggerService.deleteSoundModel(new ParcelUuid(modelUuid));
     }
 
-
     @SmallTest
     public void testDeleteGenericSoundModel() throws Exception {
-        Context context = getContext();
-        ISoundTriggerService mSoundTriggerService = ISoundTriggerService.Stub.asInterface(
-            ServiceManager.getService(Context.SOUND_TRIGGER_SERVICE));
-        SoundTriggerManager mSoundTriggerManager = (SoundTriggerManager) context.getSystemService(
-            Context.SOUND_TRIGGER_SERVICE);
+        GenericSoundModel model = new_sound_model();
 
-        byte[] data = new byte[1024];
-        mRandom.nextBytes(data);
-        UUID modelUuid = UUID.randomUUID();
-        UUID mVendorUuid = UUID.randomUUID();
-        GenericSoundModel model = new GenericSoundModel(modelUuid, mVendorUuid, data);
+        // Update sound model
+        soundTriggerService.updateSoundModel(model);
+        loadedModelUuids.add(model.uuid);
 
-        mSoundTriggerService.updateSoundModel(model);
-        mSoundTriggerService.deleteSoundModel(new ParcelUuid(modelUuid));
+        // Delete sound model
+        soundTriggerService.deleteSoundModel(new ParcelUuid(model.uuid));
+        loadedModelUuids.remove(model.uuid);
 
+        // Confirm it was deleted
         GenericSoundModel returnedModel =
-            mSoundTriggerService.getSoundModel(new ParcelUuid(modelUuid));
+                soundTriggerService.getSoundModel(new ParcelUuid(model.uuid));
         assertEquals(null, returnedModel);
     }
+
+    @LargeTest
+    public void testStartStopGenericSoundModel() throws Exception {
+        GenericSoundModel model = new_sound_model();
+
+        boolean captureTriggerAudio = true;
+        boolean allowMultipleTriggers = true;
+        RecognitionConfig config = new RecognitionConfig(captureTriggerAudio, allowMultipleTriggers,
+                null, null);
+        TestRecognitionStatusCallback spyCallback = spy(new TestRecognitionStatusCallback());
+
+        // Update and start sound model recognition
+        soundTriggerService.updateSoundModel(model);
+        loadedModelUuids.add(model.uuid);
+        int r = soundTriggerService.startRecognition(new ParcelUuid(model.uuid), spyCallback,
+                config);
+        assertEquals("Could Not Start Recognition with code: " + r,
+                android.hardware.soundtrigger.SoundTrigger.STATUS_OK, r);
+
+        // Stop recognition
+        r = soundTriggerService.stopRecognition(new ParcelUuid(model.uuid), spyCallback);
+        assertEquals("Could Not Stop Recognition with code: " + r,
+                android.hardware.soundtrigger.SoundTrigger.STATUS_OK, r);
+    }
+
+    @LargeTest
+    public void testTriggerGenericSoundModel() throws Exception {
+        GenericSoundModel model = new_sound_model();
+
+        boolean captureTriggerAudio = true;
+        boolean allowMultipleTriggers = true;
+        RecognitionConfig config = new RecognitionConfig(captureTriggerAudio, allowMultipleTriggers,
+                null, null);
+        TestRecognitionStatusCallback spyCallback = spy(new TestRecognitionStatusCallback());
+
+        // Update and start sound model
+        soundTriggerService.updateSoundModel(model);
+        loadedModelUuids.add(model.uuid);
+        soundTriggerService.startRecognition(new ParcelUuid(model.uuid), spyCallback, config);
+
+        // Send trigger to stub HAL
+        Socket socket = new Socket(InetAddress.getLocalHost(), 14035);
+        DataOutputStream out = new DataOutputStream(socket.getOutputStream());
+        out.writeBytes("trig " + model.uuid.toString() + "\r\n");
+        out.flush();
+        socket.close();
+
+        // Verify trigger was received
+        verify(spyCallback, timeout(100)).onGenericSoundTriggerDetected(any());
+    }
+
+
+    public class TestRecognitionStatusCallback extends IRecognitionStatusCallback.Stub {
+        @Override
+        public void onGenericSoundTriggerDetected(GenericRecognitionEvent recognitionEvent) {
+        }
+
+        @Override
+        public void onKeyphraseDetected(KeyphraseRecognitionEvent recognitionEvent) {
+        }
+
+        @Override
+        public void onError(int status) {
+        }
+
+        @Override
+        public void onRecognitionPaused() {
+        }
+
+        @Override
+        public void onRecognitionResumed() {
+        }
+    }
 }
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
index e3bb3e3..6d8ecd7 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
@@ -67,7 +67,7 @@
 
     // ---- delegate manager ----
     private static final DelegateManager<Bitmap_Delegate> sManager =
-            new DelegateManager<Bitmap_Delegate>(Bitmap_Delegate.class);
+            new DelegateManager<>(Bitmap_Delegate.class);
     private static long sFinalizer = -1;
 
     // ---- delegate helper data ----
@@ -314,7 +314,7 @@
 
     @LayoutlibDelegate
     /*package*/ static boolean nativeRecycle(long nativeBitmap) {
-        sManager.removeJavaReferenceFor(nativeBitmap);
+        // In our case reycle() is a no-op. We will let the finalizer to dispose the bitmap.
         return true;
     }
 
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 62f91f7..7f41348 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -492,8 +492,7 @@
     }
 
     @Override
-    public void keyguardGoingAway(boolean disableWindowAnimations,
-            boolean keyguardGoingToNotificationShade) throws RemoteException {
+    public void keyguardGoingAway(int flags) throws RemoteException {
     }
 
     @Override
diff --git a/wifi/java/android/net/wifi/RttManager.java b/wifi/java/android/net/wifi/RttManager.java
index 13abaff..87fc7fa 100644
--- a/wifi/java/android/net/wifi/RttManager.java
+++ b/wifi/java/android/net/wifi/RttManager.java
@@ -1,5 +1,6 @@
 package android.net.wifi;
 
+import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.os.Bundle;
@@ -14,6 +15,7 @@
 import android.util.Log;
 import android.util.SparseArray;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.Protocol;
 
@@ -275,12 +277,13 @@
         /** Implement the Parcelable interface {@hide} */
         public static final Creator<RttCapabilities> CREATOR =
             new Creator<RttCapabilities>() {
-               public RttCapabilities createFromParcel(Parcel in) {
+            @Override
+            public RttCapabilities createFromParcel(Parcel in) {
                     RttCapabilities capabilities = new RttCapabilities();
-                    capabilities.oneSidedRttSupported = in.readInt() == 1 ? true : false;
-                        capabilities.twoSided11McRttSupported = in.readInt() == 1 ? true : false;
-                        capabilities.lciSupported = in.readInt() == 1 ? true : false;
-                        capabilities.lcrSupported = in.readInt() == 1 ? true : false;
+                    capabilities.oneSidedRttSupported = (in.readInt() == 1);
+                        capabilities.twoSided11McRttSupported = (in.readInt() == 1);
+                        capabilities.lciSupported = (in.readInt() == 1);
+                        capabilities.lcrSupported = (in.readInt() == 1);
                         capabilities.preambleSupported = in.readInt();
                         capabilities.bwSupported = in.readInt();
                         capabilities.responderSupported = (in.readInt() == 1);
@@ -464,58 +467,57 @@
     /** pseudo-private class used to parcel arguments */
     public static class ParcelableRttParams implements Parcelable {
 
+        @NonNull
         public RttParams mParams[];
 
-        ParcelableRttParams(RttParams[] params) {
-            mParams = params;
+        /**
+         * @hide
+         */
+        @VisibleForTesting
+        public ParcelableRttParams(RttParams[] params) {
+            mParams = (params == null ? new RttParams[0] : params);
         }
 
         /** Implement the Parcelable interface {@hide} */
+        @Override
         public int describeContents() {
             return 0;
         }
 
         /** Implement the Parcelable interface {@hide} */
+        @Override
         public void writeToParcel(Parcel dest, int flags) {
-            if (mParams != null) {
-                dest.writeInt(mParams.length);
+            dest.writeInt(mParams.length);
 
-                for (RttParams params : mParams) {
-                    dest.writeInt(params.deviceType);
-                    dest.writeInt(params.requestType);
-                    dest.writeByte(params.secure ? (byte) 1 : 0);
-                    dest.writeString(params.bssid);
-                    dest.writeInt(params.channelWidth);
-                    dest.writeInt(params.frequency);
-                    dest.writeInt(params.centerFreq0);
-                    dest.writeInt(params.centerFreq1);
-                    dest.writeInt(params.numberBurst);
-                    dest.writeInt(params.interval);
-                    dest.writeInt(params.numSamplesPerBurst);
-                    dest.writeInt(params.numRetriesPerMeasurementFrame);
-                    dest.writeInt(params.numRetriesPerFTMR);
-                    dest.writeInt(params.LCIRequest ? 1 : 0);
-                    dest.writeInt(params.LCRRequest ? 1 : 0);
-                    dest.writeInt(params.burstTimeout);
-                    dest.writeInt(params.preamble);
-                    dest.writeInt(params.bandwidth);
-                }
-            } else {
-                dest.writeInt(0);
+            for (RttParams params : mParams) {
+                dest.writeInt(params.deviceType);
+                dest.writeInt(params.requestType);
+                dest.writeByte(params.secure ? (byte) 1 : 0);
+                dest.writeString(params.bssid);
+                dest.writeInt(params.channelWidth);
+                dest.writeInt(params.frequency);
+                dest.writeInt(params.centerFreq0);
+                dest.writeInt(params.centerFreq1);
+                dest.writeInt(params.numberBurst);
+                dest.writeInt(params.interval);
+                dest.writeInt(params.numSamplesPerBurst);
+                dest.writeInt(params.numRetriesPerMeasurementFrame);
+                dest.writeInt(params.numRetriesPerFTMR);
+                dest.writeInt(params.LCIRequest ? 1 : 0);
+                dest.writeInt(params.LCRRequest ? 1 : 0);
+                dest.writeInt(params.burstTimeout);
+                dest.writeInt(params.preamble);
+                dest.writeInt(params.bandwidth);
             }
         }
 
         /** Implement the Parcelable interface {@hide} */
         public static final Creator<ParcelableRttParams> CREATOR =
                 new Creator<ParcelableRttParams>() {
+                    @Override
                     public ParcelableRttParams createFromParcel(Parcel in) {
 
                         int num = in.readInt();
-
-                        if (num == 0) {
-                            return new ParcelableRttParams(null);
-                        }
-
                         RttParams params[] = new RttParams[num];
                         for (int i = 0; i < num; i++) {
                             params[i] = new RttParams();
@@ -532,8 +534,8 @@
                             params[i].numSamplesPerBurst = in.readInt();
                             params[i].numRetriesPerMeasurementFrame = in.readInt();
                             params[i].numRetriesPerFTMR = in.readInt();
-                            params[i].LCIRequest = in.readInt() == 1 ? true : false;
-                            params[i].LCRRequest = in.readInt() == 1 ? true : false;
+                            params[i].LCIRequest = (in.readInt() == 1);
+                            params[i].LCRRequest = (in.readInt() == 1);
                             params[i].burstTimeout = in.readInt();
                             params[i].preamble = in.readInt();
                             params[i].bandwidth = in.readInt();
@@ -543,6 +545,7 @@
                         return parcelableParams;
                     }
 
+                    @Override
                     public ParcelableRttParams[] newArray(int size) {
                         return new ParcelableRttParams[size];
                     }
@@ -715,11 +718,13 @@
         }
 
         /** Implement the Parcelable interface {@hide} */
+        @Override
         public int describeContents() {
             return 0;
         }
 
         /** Implement the Parcelable interface {@hide} */
+        @Override
         public void writeToParcel(Parcel dest, int flags) {
             if (mResults != null) {
                 dest.writeInt(mResults.length);
@@ -764,6 +769,7 @@
         /** Implement the Parcelable interface {@hide} */
         public static final Creator<ParcelableRttResults> CREATOR =
                 new Creator<ParcelableRttResults>() {
+                    @Override
                     public ParcelableRttResults createFromParcel(Parcel in) {
 
                         int num = in.readInt();
@@ -816,6 +822,7 @@
                         return parcelableResults;
                     }
 
+                    @Override
                     public ParcelableRttResults[] newArray(int size) {
                         return new ParcelableRttResults[size];
                     }
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index a5bfd3c..823fd26 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -21,7 +21,6 @@
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
 import android.net.DhcpInfo;
 import android.net.Network;
 import android.net.NetworkCapabilities;
@@ -666,17 +665,15 @@
     private final int mTargetSdkVersion;
 
     private static final int INVALID_KEY = 0;
-    private static int sListenerKey = 1;
-    private static final SparseArray sListenerMap = new SparseArray();
-    private static final Object sListenerMapLock = new Object();
+    private int mListenerKey = 1;
+    private final SparseArray mListenerMap = new SparseArray();
+    private final Object mListenerMapLock = new Object();
 
-    private static AsyncChannel sAsyncChannel;
-    private static CountDownLatch sConnected;
-    private static ConnectivityManager sCM;
+    private AsyncChannel mAsyncChannel;
+    private CountDownLatch mConnected;
 
-    private static final Object sThreadRefLock = new Object();
-    private static int sThreadRefCount;
-    private static HandlerThread sHandlerThread;
+    /* TODO(b/27432949): Use a common connectivity thread for this. */
+    private HandlerThread mHandlerThread;
 
     /**
      * Create a new WifiManager instance.
@@ -1482,7 +1479,7 @@
      */
     public void getTxPacketCount(TxPacketCountListener listener) {
         validateChannel();
-        sAsyncChannel.sendMessage(RSSI_PKTCNT_FETCH, 0, putListener(listener));
+        mAsyncChannel.sendMessage(RSSI_PKTCNT_FETCH, 0, putListener(listener));
     }
 
     /**
@@ -1846,25 +1843,34 @@
         public void onFailure(int reason);
     }
 
-    private static class ServiceHandler extends Handler {
+    // Ensure that multiple ServiceHandler threads do not interleave message dispatch.
+    private static final Object sServiceHandlerDispatchLock = new Object();
+
+    private class ServiceHandler extends Handler {
         ServiceHandler(Looper looper) {
             super(looper);
         }
 
         @Override
         public void handleMessage(Message message) {
+            synchronized (sServiceHandlerDispatchLock) {
+                dispatchMessageToListeners(message);
+            }
+        }
+
+        private void dispatchMessageToListeners(Message message) {
             Object listener = removeListener(message.arg2);
             switch (message.what) {
                 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
                     if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
-                        sAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
+                        mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
                     } else {
                         Log.e(TAG, "Failed to set up channel connection");
                         // This will cause all further async API calls on the WifiManager
                         // to fail and throw an exception
-                        sAsyncChannel = null;
+                        mAsyncChannel = null;
                     }
-                    sConnected.countDown();
+                    mConnected.countDown();
                     break;
                 case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
                     // Ignore
@@ -1873,7 +1879,7 @@
                     Log.e(TAG, "Channel connection lost");
                     // This will cause all further async API calls on the WifiManager
                     // to fail and throw an exception
-                    sAsyncChannel = null;
+                    mAsyncChannel = null;
                     getLooper().quit();
                     break;
                     /* ActionListeners grouped together */
@@ -1899,8 +1905,8 @@
                         WpsResult result = (WpsResult) message.obj;
                         ((WpsCallback) listener).onStarted(result.pin);
                         //Listener needs to stay until completion or failure
-                        synchronized(sListenerMapLock) {
-                            sListenerMap.put(message.arg2, listener);
+                        synchronized (mListenerMapLock) {
+                            mListenerMap.put(message.arg2, listener);
                         }
                     }
                     break;
@@ -1945,54 +1951,50 @@
         }
     }
 
-    private static int putListener(Object listener) {
+    private int putListener(Object listener) {
         if (listener == null) return INVALID_KEY;
         int key;
-        synchronized (sListenerMapLock) {
+        synchronized (mListenerMapLock) {
             do {
-                key = sListenerKey++;
+                key = mListenerKey++;
             } while (key == INVALID_KEY);
-            sListenerMap.put(key, listener);
+            mListenerMap.put(key, listener);
         }
         return key;
     }
 
-    private static Object removeListener(int key) {
+    private Object removeListener(int key) {
         if (key == INVALID_KEY) return null;
-        synchronized (sListenerMapLock) {
-            Object listener = sListenerMap.get(key);
-            sListenerMap.remove(key);
+        synchronized (mListenerMapLock) {
+            Object listener = mListenerMap.get(key);
+            mListenerMap.remove(key);
             return listener;
         }
     }
 
     private void init() {
-        synchronized (sThreadRefLock) {
-            if (++sThreadRefCount == 1) {
-                Messenger messenger = getWifiServiceMessenger();
-                if (messenger == null) {
-                    sAsyncChannel = null;
-                    return;
-                }
+        Messenger messenger = getWifiServiceMessenger();
+        if (messenger == null) {
+            mAsyncChannel = null;
+            return;
+        }
 
-                sHandlerThread = new HandlerThread("WifiManager");
-                sAsyncChannel = new AsyncChannel();
-                sConnected = new CountDownLatch(1);
+        mHandlerThread = new HandlerThread("WifiManager");
+        mAsyncChannel = new AsyncChannel();
+        mConnected = new CountDownLatch(1);
 
-                sHandlerThread.start();
-                Handler handler = new ServiceHandler(sHandlerThread.getLooper());
-                sAsyncChannel.connect(mContext, handler, messenger);
-                try {
-                    sConnected.await();
-                } catch (InterruptedException e) {
-                    Log.e(TAG, "interrupted wait at init");
-                }
-            }
+        mHandlerThread.start();
+        Handler handler = new ServiceHandler(mHandlerThread.getLooper());
+        mAsyncChannel.connect(mContext, handler, messenger);
+        try {
+            mConnected.await();
+        } catch (InterruptedException e) {
+            Log.e(TAG, "interrupted wait at init");
         }
     }
 
     private void validateChannel() {
-        if (sAsyncChannel == null) throw new IllegalStateException(
+        if (mAsyncChannel == null) throw new IllegalStateException(
                 "No permission to access and change wifi or a bad initialization");
     }
 
@@ -2017,7 +2019,7 @@
         validateChannel();
         // Use INVALID_NETWORK_ID for arg1 when passing a config object
         // arg1 is used to pass network id when the network already exists
-        sAsyncChannel.sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID,
+        mAsyncChannel.sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID,
                 putListener(listener), config);
     }
 
@@ -2037,7 +2039,7 @@
     public void connect(int networkId, ActionListener listener) {
         if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative");
         validateChannel();
-        sAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, putListener(listener));
+        mAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, putListener(listener));
     }
 
     /**
@@ -2061,7 +2063,7 @@
     public void save(WifiConfiguration config, ActionListener listener) {
         if (config == null) throw new IllegalArgumentException("config cannot be null");
         validateChannel();
-        sAsyncChannel.sendMessage(SAVE_NETWORK, 0, putListener(listener), config);
+        mAsyncChannel.sendMessage(SAVE_NETWORK, 0, putListener(listener), config);
     }
 
     /**
@@ -2080,7 +2082,7 @@
     public void forget(int netId, ActionListener listener) {
         if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative");
         validateChannel();
-        sAsyncChannel.sendMessage(FORGET_NETWORK, netId, putListener(listener));
+        mAsyncChannel.sendMessage(FORGET_NETWORK, netId, putListener(listener));
     }
 
     /**
@@ -2095,7 +2097,7 @@
     public void disable(int netId, ActionListener listener) {
         if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative");
         validateChannel();
-        sAsyncChannel.sendMessage(DISABLE_NETWORK, netId, putListener(listener));
+        mAsyncChannel.sendMessage(DISABLE_NETWORK, netId, putListener(listener));
     }
 
     /**
@@ -2124,7 +2126,7 @@
     public void startWps(WpsInfo config, WpsCallback listener) {
         if (config == null) throw new IllegalArgumentException("config cannot be null");
         validateChannel();
-        sAsyncChannel.sendMessage(START_WPS, 0, putListener(listener), config);
+        mAsyncChannel.sendMessage(START_WPS, 0, putListener(listener), config);
     }
 
     /**
@@ -2136,7 +2138,7 @@
      */
     public void cancelWps(WpsCallback listener) {
         validateChannel();
-        sAsyncChannel.sendMessage(CANCEL_WPS, 0, putListener(listener));
+        mAsyncChannel.sendMessage(CANCEL_WPS, 0, putListener(listener));
     }
 
     /**
@@ -2601,10 +2603,8 @@
 
     protected void finalize() throws Throwable {
         try {
-            synchronized (sThreadRefLock) {
-                if (--sThreadRefCount == 0 && sAsyncChannel != null) {
-                    sAsyncChannel.disconnect();
-                }
+            if (mAsyncChannel != null) {
+                mAsyncChannel.disconnect();
             }
         } finally {
             super.finalize();